[英]BOOST::ASIO. Making sure io_service.run() is invoked only after async_receive(…) is called?
I have a problem where two threads are called like this, one after another. 我有一个问题,两个这样的线程一个接一个地调用。
new boost::thread( &SERVER::start_receive, this);
new boost::thread( &SERVER::run_io_service, this);
Where the first thread calls this function. 第一个线程在哪里调用此函数。
void start_receive()
{
udp_socket.async_receive(....);
}
and the second thread calls, 第二个线程调用
void run_io_service()
{
io_service.run();
}
and sometimes the io_service
thread ends up finishing before the start_receive()
thread and then the server cannot receive packets. 有时
io_service
线程在start_receive()
线程之前结束工作,然后服务器无法接收数据包。
I thought about putting a sleep function between the two threads to wait a while for the start_receive()
to complete and that works but I wondered if there was another sure fire way to make this happen? 我曾考虑过在两个线程之间放置一个sleep函数,等待一会儿,以便
start_receive()
完成并且可以工作,但我想知道是否还有另一种可靠的方法可以实现这一目标?
If you want to keep the io_service
running, create a work
object: 如果要保持
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.
The nice thing about this approach is that the work
object above will keep the svc
object "running", but not block any other operations on it. 这种方法的
svc
是,上面的work
对象将使svc
对象保持“运行”状态,但不会阻止对其进行任何其他操作。
When you call io_service.run()
, the thread will block, dispatching posted handlers until either: 当您调用
io_service.run()
,线程将阻塞,分派已发布的处理程序,直到发生以下任何一种情况:
There are no io_service::work
objects associated with the io_service
, or 没有与
io_service
关联的io_service::work
对象,或者
io_service.stop()
is called. io_service.stop()
被调用。
If either of these happens, the io_service
enters the stopped state and will refuse to dispatch any more handlers in future until its reset()
method is called. 如果这两种情况之一发生,
io_service
将进入停止状态,并且以后将拒绝分派任何其他处理程序,直到调用其reset()
方法为止。
Every time you initiate an asynchronous operation on an io object associated with the io_service, an io_service::work object is embedded in the asynchronous handler. 每次对与io_service关联的io对象启动异步操作时,都会在异步处理程序中嵌入io_service :: work对象。
For this reason, point (1) above cannot happen until the asynchronous handler has run. 因此,在异步处理程序运行之前,上面的点(1)不会发生。
this code therefore will guarantee that the async process completes and that the asserts pass: 因此,此代码将确保异步过程完成并且断言通过:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.