boost :: asio io_service线程池

Dav*_*vid 15 c++ networking boost boost-asio c++11

为io_service设置线程池的正确用法是什么?文档中的这两个陈述让我失望:

io_service对象::运行

run()函数的正常退出意味着io_service对象已停止(stopped()函数返回true).除非事先调用reset(),否则对run(),run_one(),poll()或poll_one()的后续调用将立即返回.

io_service对象::复位

当由于io_service被停止或用完而导致先前调用这些函数时,必须在run(),run_one(),poll()或poll_one()函数的任何第二次或更高版本的调用之前调用此函数.工作.

这是我目前正在做的事情:

boost::thread_group     m_Threads;
boost::asio::io_service m_IoService;
boost::barrier          m_Barrier(numThreads);

for( unsigned int i = 0; i < numThreads; ++i )
{
    m_Threads.create_thread(
        [&]()
        {
            for(;;)
            {
                m_IoService.run();

                if( m_Barrier.wait() )  //  will only return true for 1 thread
                {
                    m_IoService.reset();
                }
                m_Barrier.wait();
            }
        });
}

m_IoService.stop();
m_Threads.interrupt_all();
m_Threads.join_all();
Run Code Online (Sandbox Code Playgroud)

一切似乎如果我只是把做工精细m_IoService.run()无限循环(该文件似乎表明应该不会是这种情况).什么是正确的方法?

Nim*_*Nim 17

run()是一个阻塞调用,并将在返回之前执行它可以执行的所有事件.只有在没有更多事件需要处理时它才会返回.一旦它返回,你必须reset()run()再次呼叫之前调用io_service .

您可以调用多个线程run()- 这不是问题,只要io_service有一些工作要做,您就不需要无限循环.正常的模式是work在io_service上创建一个强制run()永不返回的对象.这意味着你必须stop()在完成后明确地调用io_service,因为它永远不会自然退出.

如果您work在io_service上设置了它,它将永远不会自然退出,因此您永远不需要调用reset().

work some_work(m_IoService); // this will keep the io_service live.

for( unsigned int i = 0; i < numThreads; ++i )
{
  m_Threads.create_thread(
    [&]()
    {
      m_IoService.run();
    });
}
Run Code Online (Sandbox Code Playgroud)

现在所有线程都在io_service上调度事件

// Now post your jobs
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads
m_IoService.post(boost::bind(...)); // this will be executed in one of the threads

m_IoService.stop(); // explicitly stop the io_service
// now join all the threads and wait for them to exit
Run Code Online (Sandbox Code Playgroud)

  • 我认为总是让``run()``干净地退出是更清洁的.如果你需要确保``io_service``在你没有事件时保持活着,创建一个``work``对象并在它退出时将其销毁.这样,所有未决事件都将触发,允许清理所有内容. (4认同)
  • @Dave - 它没有意义,执行只会在`run()`退出时达到这一点. (3认同)