提升::亚洲.确保仅在调用async_receive(..)后调用io_service.run()?

BOOST::ASIO. Making sure io_service.run() is invoked only after async_receive(...) is called?

本文关键字:调用 io run service 亚洲 确保 async 提升 receive      更新时间:2023-10-16

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

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()并且有效,但我想知道是否有另一种确定的火方法可以实现这一目标?

当你调用io_service.run()时,线程将阻塞,调度已发布的处理程序,直到:

  1. 没有与io_service相关联的io_service::work对象,或者

  2. io_service.stop()被称为。

如果发生上述任一情况,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 

如果要保持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对象保持"运行",但不会阻止对其执行任何其他操作。