3

現在、ハンドラーをio_serviceに投稿し、スレッドプールで実行しています。

io_serv.post( boost::bind(&Class::bar, p1, p2) );

私の労働者はこの機能を実行します:

m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id()
        << "] Thread Start" << std::endl;
m_mutex.unlock();

size_t tasks = m_serv.run();

m_mutex.lock();
std::cout << "[" << boost::this_thread::get_id() << "] accomplished "
          << tasks << " tasks" << std::endl;
m_mutex.unlock();

これまでのところ良好ですが、アクティブな(ただし待機中の)スレッドを強制終了せずに、ハンドラーキューが空になったときにイベントをトリガーしたいと思います。

それは可能ですか、そしてどのように?

4

1 に答える 1

3

初めてasioをキューディスパッチャーとして使用しているのを目にしました。悪くないテクニックだと思います。

さて、ハンドラーを提供するためにio_service::runを実行していることをお勧めします。ドキュメントに記載されているように、実行はio_serviceが停止するか、すべての作業が終了するまでブロックされます。したがって、 io_service :: run:の後に「空のキューイベント」を実行できます。

while( !finished ) {
    io_serv.run();
    io_serv.reset();
    io_serv.post( boost::bind(&Class::fill_queue, instance) );
}

これは、このio_serviceに他のasioアクティビティがなく、io_service::workを使用していない場合です。

コメントで述べたように、io_service :: workを使用しているため、プランAは失敗しました(このクラスは空のキューでの終了を防ぐため、機能しません)。さて、あなたはスレッドジョブのために-sのio_serv.post()各束の後に行うことができます。io_serv.post()ハンドラーには、他のスレッドが作業を終了する間、 boost::conditionで待機することを含めることができます。実際の仕事の後でこれを行うようpost()に、asioはすべての仕事を派遣した後にそれを呼び出すと思いますが、調査の対象です。とにかく、post()条件がまだ準備できていない場合、そのハンドラーは現在のスレッドを解放するために自分自身を再設定できます。

しかし、最も簡単な方法は、io_service::workをequialentwhileconstruct置き換えることだと思います。

于 2012-11-22T17:42:39.333 に答える