asynchronous - Asio的执行流程是什么?
问题描述
我有一个测试程序如下:
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”)之后,“timer2 expired”行仍然在“timer1 cancelled”行之前打印。
在我的想象中,boost:asio 是围绕“epoll”编写的,它可以处理“事件”,如来自网络的传入消息(timer2 到期)和“块”,如在单个线程中写入磁盘(睡眠)。但是为什么在“sleep_for”之后没有显示“timer1 cancelled”这一行?
问题 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 done -> heavy_job: 这意味着 wait_funcs 检查检测到不安全行为
对不起我的演示,我是 boost:asio 的新手,很困惑。
解决方案
您可以将其io_service
视为生产者-消费者队列:每当异步操作完成(或中止)时,其完成处理程序就会被推入队列;而另一方面,io_service::run()
从队列中获取这些处理程序并调用它们。
还要注意,只要你的程序是单线程的(并且不使用协同程序),所有的完成处理程序总是一个接一个地顺序执行。
因此,在您的第一个示例中,t2
计时器首先到期,然后调用完成处理程序。t1
在前一个完成之前,不会从队列中获取的处理程序- 不管需要多长时间。
这同样适用于您的第二个示例: 的完成处理程序timer1
正在 的上下文中运行io_service::run
,因此后者无法获取任何后续处理程序,直到前一个处理程序完成。因此,如果heavy_job()
完成时间过长,所有其他处理程序将被卡在队列中。
推荐阅读
- c++ - 使用 std::for_each 迭代和打印 std::map
- html - HTML 表格未按我希望的那样出现
- r - 网络在 R Fantasy Premier League 中抓取表格
- html - 在图像中显示的 Wordpress 问题
- python - TclError:Kaggle 中没有显示名称和 $DISPLAY 环境变量
- r - R - 加入列后ggplotly抛出错误
- javascript - (Javascript 和 Html)函数执行另一个未被告知执行的函数
- c# - C# Parallel Foreach 重复方法
- ios - 有没有更好的方法来排除 tvOS 的 navigationBarTitle?
- ios - 如何在下一个屏幕的自定义表格视图单元格中显示多个选定的行