我有一个如下的测试程序:
io_service io;
deadline_timer t1(io);
deadline_timer t2(io);
t1.expires_from_now(boost::posix_time::seconds(10));
t1.async_wait([](const boost::system::error_code &error) {
if (error == boost::asio::error::operation_aborted) {
cout << "timer1 canceled" << endl;
} else {
cout << "timer1 expired" << endl;
}
});
t2.expires_from_now(boost::posix_time::seconds(2));
t2.async_wait([&t1](const boost::system::error_code &error) {
if (error == boost::asio::error::operation_aborted) {
cout << "timer2 canceled" << endl;
} else {
t1.cancel();
for (int i = 0; i < 5000000; i++) {
cout << i << endl;
}
# usleep(1000000);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
cout << "timer2 expired" << endl;
}
});
io.run();
我想知道当timer2到期并取消timer1时,“ timer1已取消”和“ timer2到期”中的哪一个将首先打印?
结果是“ timer2已过期”。这是有道理的,因为单线程程序将执行直到出现一些“块”。
但是,在插入“ sleep_for(1000ms)”行(这会阻止执行,将过程转移到“ Sleep”)之后,在“ timer1取消”行之前仍打印“ timer2 expired”行。
在我的想象中,boost:asio是围绕“ epoll”编写的东西,它可以在“事件”(例如来自网络的传入消息,timer2到期)与“块”(例如,在单个线程中写入磁盘)之间进行处理。但是,为什么在“ sleep_for”之后没有显示“ timer1 canceled”行呢?
问题2:假设一个程序在一个线程中处理网络请求和Chrono作业。
void fun1(){
timer1.expire_from_now(3s);
timer1.async_wait([](const & error){
cout<<"timer1 expired";
heavy_job();
});
}
fun1已过期,已执行cout<<"timer1 expired"
,但未执行。沉重的工作呢。此时,来自网络的请求触发了fun2:
int wait_funcs= timer1.expire_from_now(3s);
if (wait_funcs == 0 ){
job2();
}else{
job3();
}
以下哪种情况会发生?
heavy_job done-> job2:这意味着func1不会被fun2打断,fun2将在fun1完成(或阻止?)后运行
job2完成-> heavy_job:这意味着wait_funcs检查检测到不安全行为
对不起我的示范,我是新加入的:asio和困惑。
您可以将其io_service
视为生产者-消费者队列:每当异步操作完成(或中止)时,其完成处理程序便被推入队列;另一方面,io_service::run()
从队列中获取这些处理程序并调用它们。
还要注意,只要您的程序是单线程的(并且不使用协例程),所有完成处理程序将始终按顺序依次执行。
因此,在您的第一个示例中,t2
计时器首先到期,并且调用了完成处理程序。t1
在上一个操作完成之前,不会从队列中提取的处理程序-花费多长时间都没有关系。
您的第二个示例也是如此:的完成处理程序timer1
在的上下文中运行io_service::run
,因此后者在完成前一个处理程序之前无法获取任何后续处理程序。因此,如果heavy_job()
完成时间太长,所有其他处理程序将被卡在队列中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句