6

Boost の ASIO ディスパッチャに重大な問題があるようで、回避策が見つからないようです。症状は、pthread_cond_waitブロックする必要がある保留中の I/O 操作があるにもかかわらず、ディスパッチを待機している唯一のスレッドが feven に残されることですepoll_wait

poll_oneこの問題は、ゼロが返されるまでループ内で1 つのスレッド呼び出しを行うことで、最も簡単に再現できます。これにより、スレッドの呼び出しがループから抜け出している間、スレッドの呼び出しrunがスタックしたままになる可能性があります。おそらく、io_service はそのスレッドがブロックに戻ることを期待していますが、そうする義務はなく、その期待は致命的なようです。pthread_cond_waitpoll_oneepoll_wait

スレッドを s に静的に関連付ける必要はありますio_serviceか?

デッドロックを示す例を次に示します。これは、他のスレッドが移動したため、この io_service を処理する唯一のスレッドです。確実に保留中のソケット操作があります:

#0 pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 boost::asio::detail::posix_event::wait<boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex> > (...) at /usr/include/boost/asio/detail/posix_event.hpp:80
#2 boost::asio::detail::task_io_service::do_run_one (...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:405
#3 boost::asio::detail::task_io_service::run (...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:146

I/O キューを処理しているスレッドが、I/O ソケットの準備状況チェックでブロックしているスレッドであり、ディスパッチ関数を呼び出す場合、IO サービスでブロックされている他のスレッドがある場合、それは信号を送る必要があります。現在、その時点で実行する準備ができているハンドラーがある場合にのみ通知します。ただし、ソケットの準備状況をチェックするスレッドはありません。

4

1 に答える 1