0

リクエストから情報を取得し、すべてをキューに入れて処理するtcpサーバーを設計しています。私はすべてのWebインタラクションを処理するためにasioWebサーバーを使用しています。すべてをプロセスとしてキューに入れる効果的な方法を探しています。私は今これと同じようにこれを行うためにブースト信号とグローバルベクトルを使用しています。

void request_handler::handle_request(request &req, reply &rep)
{
   std::string parsedInfo = parse_request(req); 
   shared_queue.push_back(parsedInfo);
   new_entry();
}

new_entryはブースト信号です

    boost::signal<void ()> new_entry;

現在、シグナルをキャッチするためのシグナルハンドラークラスがあります。

void sig_handler::process_next()
{
    boost::try_mutex::scoped_try_lock lock(guard);
    if(!lock)
       return;
    while(!shared_queue.empty())
    {
        ... //Do Stuff
        std::string cur_entry = shared_queue.at(0);
        shared_queue.erase(shared_queue.begin());
        ... //Do more stuff
    } 
}

私の目標は、ベクターキューに情報がある場合、およびベクターに何かがプッシュされるたびに、ベクターキューをクリアすることです。ポーリングは極力避けたいです。この部分も私が期待するように機能していると思います。ただし、バックトレースに基づいて、共有キューに情報をプッシュすることでクラッシュが発生することがあります。これは、1秒間に数千のトランザクションを実行しようとしたときにのみ発生するため、マルチスレッド環境でのデバッグが困難になります。私のバックトレースはここにあります:

Error: signal 11:
./UpdateServer/build/UpdateServer(_Z7handleri+0x18)[0x469f68]
/lib/x86_64-linux-gnu/libc.so.6(+0x364a0)[0x7fbbdd67a4a0]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSsC1ERKSs+0xb)[0x7fbbddfb4f2b]
./UpdateServer/build/UpdateServer[0x4749d0]
./UpdateServer/build/UpdateServer(_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs+0x111)[0x476521]
./UpdateServer/build/UpdateServer(_ZN15request_handler14handle_requestERK7requestR5reply+0x3d3)[0x475873]
./UpdateServer/build/UpdateServer(_ZN10connection11handle_readERKN5boost6system10error_codeEm+0x234)[0x46c774]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail14strand_service8dispatchINS1_7binder2INS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS5_5list3INS5_5valueINS_10shared_ptrIS9_EEEEPFNS_3argILi1EEEvEPFNSK_ILi2EEEvEEEEESB_mEEEEvRPNS2_11strand_implET_+0xcd)[0x47216d]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS5_5list3INS5_5valueINS_10shared_ptrIS9_EEEEPFNS_3argILi1EEEvEPFNSK_ILi2EEEvEEEEEEclISB_mEEvRKT_RKT0_+0xd9)[0x472439]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail18completion_handlerINS1_17rewrapped_handlerINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS8_5list3INS8_5valueINS_10shared_ptrISC_EEEEPFNS_3argILi1EEEvEPFNSN_ILi2EEEvEEEEEEESE_mEESV_EEE11do_completeEPNS1_15task_io_serviceEPNS1_25task_io_service_operationESG_m+0x1e5)[0x4726f5]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail14strand_service8dispatchINS1_17rewrapped_handlerINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS9_5list3INS9_5valueINS_10shared_ptrISD_EEEEPFNS_3argILi1EEEvEPFNSO_ILi2EEEvEEEEEEESF_mEESW_EEEEvRPNS2_11strand_implET_+0x2ad)[0x472aed]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail19asio_handler_invokeINS1_7binder2INS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS7_5list3INS7_5valueINS_10shared_ptrISB_EEEEPFNS_3argILi1EEEvEPFNSM_ILi2EEEvEEEEEEESD_mEES6_SU_EEvRT_PNS4_IT0_T1_EE+0x15f)[0x472d3f]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail23reactive_socket_recv_opINS0_17mutable_buffers_1ENS1_15wrapped_handlerINS0_10io_service6strandENS_3_bi6bind_tIvNS_4_mfi3mf2Iv10connectionRKNS_6system10error_codeEmEENS7_5list3INS7_5valueINS_10shared_ptrISB_EEEEPFNS_3argILi1EEEvEPFNSM_ILi2EEEvEEEEEEEE11do_completeEPNS1_15task_io_serviceEPNS1_25task_io_service_operationESF_m+0xce)[0x472ede]
./UpdateServer/build/UpdateServer(_ZN5boost4asio6detail15task_io_service3runERNS_6system10error_codeE+0x79a)[0x47ceea]
./UpdateServer/build/UpdateServer(_ZN5boost4asio10io_service3runEv+0x25)[0x47d1d5]
/usr/lib/libboost_thread.so.1.48.0(+0xdda9)[0x7fbbdecd4da9]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a)[0x7fbbdd42ee9a]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fbbdd737cbd]

この線./UpdateServer/build/UpdateServer(_ZNSt6vectorISsSaISsEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPSsS1_EERKSs+0x111)[0x476521]

std :: vector insert iteratorにデマングルしているようです。これが、私のプログラムが共有ベクトル挿入でクラッシュしていると私が信じている理由です(プログラムに他の文字列のベクトルがあるとは思わない)が、私はかなりポジティブです。挿入と読み取りの両方で、安全な方法で私のベクトル。

ですから、私の質問は、共有ベクトルに情報をプッシュするときに、クラッシュを引き起こすことを心配しなければならない競合状態の問題があるのではないかということだと思います。そして、私が取っているアプローチは実行可能なアプローチですか、それとも何らかの方法でデザインを再考する必要がありますか?さらに情報が必要な場合はお知らせください。できる限りの情報を提供させていただきます。

ありがとうございました

4

1 に答える 1

2

stdデータ構造は (ほとんどの場合)スレッド セーフではないため、複数のスレッドが同時にアクセスする場合は、追加の同期が必要になります。あなたの場合、push_back別のスレッドが呼び出している間に、あるスレッドが呼び出している可能性がありますerase。これにより、未定義の動作が発生します。これを修正するには、push_backと の両方eraseを同じロックで保護する必要があります。C++ 標準ライブラリのスレッド セーフについてググって、詳細を読むことをお勧めします。


また、vectorここで a を使用することはおそらく最良の選択ではありません。代わりにstd::queueを調べる必要があります。eraseの最初の要素がvector、ベクター内のすべての文字列を 1 つ下にコピーする必要がある場合、これは非常にコストがかかる可能性があります 。queueこの問題に悩まされることはありません。

于 2013-02-13T02:27:30.217 に答える