的boost :: ASIO。确保在调用async_receive(...)之后才调用io_service.run()?

时间:2017-07-05 20:00:07

标签: c++ multithreading boost-asio

我有一个问题,就是这样一个接一个地调用两个线程。

new boost::thread( &SERVER::start_receive, this);

new boost::thread( &SERVER::run_io_service, this);

第一个线程调用此函数的地方。

void start_receive()
{   
    udp_socket.async_receive(....);
}

,第二个线程调用,

void run_io_service()
{  
    io_service.run();
}

有时io_service线程最终在start_receive()线程之前完成,然后服务器无法接收数据包。

我考虑在两个线程之间放置一个睡眠函数等待start_receive()完成并且这有效但是我想知道是否还有另一种确定的火灾方法来实现这一点?

2 个答案:

答案 0 :(得分:2)

如果您想让io_service保持运行,请创建一个work对象:

boost::asio::io_service svc;
auto work = std::make_shared<boost::asio::io_service::work>(svc);
svc.run(); // this will block as long as the work object is valid.

这种方法的好处是上面的work对象将保持svc对象&#34;运行&#34;,但不阻止其上的任何其他操作。

答案 1 :(得分:2)

当您致电io_service.run()时,该线程将阻止,调度已发布的处理程序,直到:

  1. io_service::work

  2. 没有关联io_service个对象
  3. io_service.stop()被调用。

  4. 如果其中任何一个发生,io_service进入停止状态,并且将来拒绝分派任何处理程序,直到调用reset()方法。

    每次在与io_service关联的io对象上启动异步操作时,都会在异步处理程序中嵌入io_service :: work对象。

    因此,在异步处理程序运行之前,上述第(1)点不会发生。

    因此,此代码将保证异步过程完成并且断言传递:

    asio::io_service ios;    // ios is not in stopped state
    assert(!ios.stopped());
    auto obj = some_io_object(ios);
    bool completed = false;
    obj.async_something(..., [&](auto const& ec) { completed = true; });
    // nothing will happen yet. There is now 1 work object associated with ios
    assert(!completed);
    
    auto ran = ios.run();
    assert(completed);
    assert(ran == 1);    // only 1 async op waiting for completion.
    assert(ios.stopped());  // io_service is exhausted and no work remaining
    
    ios.reset();
    assert(!ios.stopped());  // io_service is ready to run again