2017-06-15 3 views
1

これはhereの質問です。Boostでシリアル化された構造を送信していますが、入力ストリームのエラーが発生しています

私は2016 Marathon of Parallel Programmingから最初のチャレンジを解決しています。この質問は、文字列の解析という最初の課題に関連しています。

あなたはhereの設定問題を読めば、明らかに第五ステップは、だから私はZeroMQして以下にこれを実装することにより、ソリューションを並列化し、ブースト(シリアライズしたい3ページの

[Try all derivations recursively.]である、並列化メインスレッドにワーカースレッドと結果のためにジョブを含む構造res_packageは、):

enter image description here

mainでPUSHソケットグループは、タスクを分散するために使用されます。 mainPULLソケットグループはワーカースレッドからの結果を収集します。最後に、PUBソケットグループは、ワーカーにキル信号を送信するためのものです。

は、そうでない場合はmainPUSHソケットは、最初に接続されている労働者に仕事の多くを送信し、mainworker間の同期を行うためのステップがあります。

メインスレッドは、毎回ワーカースレッドにそのPUSHエンドポイントを同期させる#worker_numをプッシュし、PULLエンドポイントから確認メッセージを読み込みます。メインスレッドが#worker_numの確認メッセージを取得した場合は、同期が完了しています。ワーカーからの同期msgのフォーマットは、文字列内のワーカースレッドのIDです。したがって、スレッド0は、文字列中の0をメインスレッドに戻します。メインスレッドは、(文法によって受け付けられた文字列を意味する)trueとしての第2のフィールドとEvalある意味のある結果を受信した場合

、メインスレッドは、キル信号を発行することになります。すべてのワーカースレッドがbool exit_confirmedのフィールドstruct res_packageに確認を返すと、メインスレッドはワーカースレッドに参加し、最終結果を出力します。

問題は、私はBoostからランタイムエラーが発生しています。

# ./spec < ./spec.in 
main() : creating thread, 0 
thread 0 receives: sync 
to_string 0 
thread 0 sends: 0, with size: 1 
thread 0 sync done 
pass 0 to if_sync_done 
main thread receives sync msg from thread 0 
sync done in main thread 
456Dynamic exception type: boost::archive::archive_exception 
std::exception::what: input stream error 

この例外は912行目(GDBバックトレースから)によって発生します。だから私が推測しているのは、問題はポインタがぶら下がっていることです。あるいは、909行目で受信されたものが何らかの形で切り捨てられています。しかし、私はさらに進む方法を知らない。 spec.ccspec.hh、あなたがhereからMakefile

元のプロジェクトをダウンロードすることができます:

はあなたが必要とするいくつかのファイルがありますが、私のプロジェクトをビルドするには。テストには spec.injudge.inがあります。Ubuntuの上の依存関係をインストールするには

、実行します。

apt-get install -y libzmqpp3 libzmqpp-dev libzmq5 libzmq5-dbg libboost-all-dev build-essential g++ 

一つの重要なデータ構造は次のとおりです。

struct res_package 
{ 
    int i; 
    Set <Stack> ls; // from worker thread to main thread 
    Stack s; // from main thread to worker thread, job to process 
    bool if_accepted; 
    bool exit_confirmed; 
    Eval res; 
    bool set_nonempty; 

// striped..... 

    template <typename Archive> 
    void serialize(Archive& ar, const unsigned int version) 
    { 
    ar & i; 
    ar & if_accepted; 
    ar & exit_confirmed; 
    ar & s; 
    ar & ls; 
    ar & res; 
    ar & set_nonempty; 
    } 
} 

ワーカースレッドがStack sを受け取り、文字列がルールsで受け入れることができたかどうかを確認します。そうであれば、if_acceptedをtrueに設定し、Eval resを返信します。存在しない場合、複数の可能なルールが見つかった場合は、すべての可能なルールのセットを返信し、を返し、bool set_nonemptyをtrueに設定して、それらのルールを配布するmainを示します。

あなたが混乱していると思われる場合は、plsさんからコメントがあります。

答えて

0

あなたはポストにシリアル化コードが含まれていませんでしたが、私はspec.ccでそれを見つけた:

ここ
{ 
    std::ostringstream obuffer; 
    boost::archive::text_oarchive oarchive(obuffer); 

    tmp.exit_confirmed = true; 
    oarchive & tmp; 
    std::string req_str(obuffer.str()); 
    zmq::message_t res_msg(req_str.size()); 
    memcpy((void *)res_msg.data(), req_str.data(), req_str.size()); 
    sendres_socket.send(res_msg); 
} 

アーカイブが閉じられる前に、ストリームを送信します。明示的に閉じたり、有効期間を制限してみてください:

{ 
    std::ostringstream obuffer; 
    { 
     boost::archive::text_oarchive oarchive(obuffer); 

     tmp.exit_confirmed = true; 
     oarchive & tmp; 
    } 
    std::string req_str(obuffer.str()); 
    zmq::message_t res_msg(req_str.size()); 
    memcpy((void *)res_msg.data(), req_str.data(), req_str.size()); 
    sendres_socket.send(res_msg); 
} 
+0

アーカイブを明示的に閉じる方法を示す例を投稿できますか? thx –

+0

このコードはすでに達成しています – sehe

+0

hmm。ですから、archive.close()を実行する 'close()'のような関数はありません。大丈夫... –

関連する問題