使用deadline_timer和io_service :: post时遇到问题如下:
#include "boost/asio.hpp"
#include "boost/thread.hpp"
int main()
{
boost::asio::io_service io_service;
boost::asio::deadline_timer timer1(io_service);
boost::asio::deadline_timer timer2(io_service);
timer1.expires_from_now(boost::posix_time::seconds(1));
timer1.async_wait([](const boost::system::error_code& error) {
boost::this_thread::sleep(boost::posix_time::seconds(5));
printf("1 ");
});
timer2.expires_from_now(boost::posix_time::seconds(2));
timer2.async_wait([](const boost::system::error_code& error) {
printf("2 ");
});
boost::thread t([&io_service]() {
boost::this_thread::sleep(boost::posix_time::seconds(5));
io_service.post([]() {
printf("3 ");
});
io_service.post([]() {
printf("4 ");
});
});
io_service.run();
t.join();
getchar();
return 0;
}
我认为结果是“1 2 3 4”但结果是“1 3 4 2”。任何人都可以告诉我如何使用boost库来执行timer2(打印“2”)的回调作为结果“1 2 3 4”(并且不要改变timer1和timer2的过期时间)。
非常感谢!
答案 0 :(得分:0)
这实际上是一个非常复杂的例子。
io_service
将在主线程上运行。这是操作顺序
主线程:
io_service.run()
)辅助主题:
首先,在调用io_service
之前,io_service.run()
不执行任何操作。
调用io_service.run()
后,将安排将来1秒的计时器。当该计时器触发时,它首先会在打印1之前休眠5秒钟。
当该线程正在执行时,辅助线程也会出现,并且会休眠5秒钟。在timer1
的处理程序中执行的计时器完成之前,将设置并调度此线程。由于这两个线程都会休眠5秒钟,因此“2”和“3”会立即发布到io_service
。
现在事情变得有点棘手了。 timer2
的超时似乎现在应该已经过期(将来至少5秒),但在处理io_service
时有两个命令直接发布到timer1
}}
似乎在实现细节中,boost优先于截止时间计时器操作直接发布的操作。
答案 1 :(得分:0)
第一个计时器到期阻止io(主)线程运行,同时另一个线程将一些项目发布到asio工作队列,一旦计时器1的回调完成,第二个计时器到期就会导致回调排队但没有执行。从“3”开始已经排队的“4”(当“1”阻塞主线程时),它们先于“2”
asio的意思是不阻止。通过在第一个定时器回调(睡眠)中放置长时间运行的工作,您已经阻止了io线程及时运行。您应该将该工作卸载到专用线程中,并将其完成发布回asio。
答案 2 :(得分:0)
let myButton = NSButton()
myButton.title = "OK"
myButton.bezelStyle = .RoundedBezelStyle
let titleBarView = window!.standardWindowButton(.CloseButton)!.superview!
titleBarView.addSubview(myButton)
myButton.translatesAutoresizingMaskIntoConstraints = false
titleBarView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[myButton]-2-|", options: [], metrics: nil, views: ["myButton": myButton]))
titleBarView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-1-[myButton]-3-|", options: [], metrics: nil, views: ["myButton": myButton]))
不保证处理程序的调用顺序。从理论上讲,可以按任何顺序调用处理程序,其中一些排列很不可能。
如果需要以非常特定的顺序调用处理程序,那么请考虑以强制执行所需处理程序链的方式重构异步调用链。此外,可能会发现有必要使用strand提供的保证顺序的处理程序调用。考虑不要通过脆弱的睡眠和计时器来控制复杂的处理程序调用。
答案 3 :(得分:0)
你的第一个问题是你试图阻止处理程序内部:
timer1.expires_from_now(boost::posix_time::seconds(1));
timer1.async_wait([](const boost::system::error_code& error) {
boost::this_thread::sleep(boost::posix_time::seconds(5)); // <--- HERE
printf("1 ");
});
上述代码中发生的情况是,在timer1
等待一秒后,它会将回调发布到io_service
。在io_service::run
函数内部执行此回调,但此执行在主线程内部发生,因此它会暂停五秒钟,从而阻止timer2
将其处理程序发布到io_service
。它一直执行到程序执行的第六秒(6 = 5 + 1)。
同时线程t
被执行,在程序执行的第五秒,它将这两个printf(&#34; 3&#34;)和printf(&#34; 4&#34;)发布到{{ 1}}。
io_service
一旦来自boost::thread t([&io_service]() {
boost::this_thread::sleep(boost::posix_time::seconds(5));
io_service.post([]() {
printf("3 ");
});
io_service.post([]() {
printf("4 ");
});
});
的处理程序取消阻止,它就允许timer1
将其处理程序发布到timer2
。这又发生在程序执行的第六秒,也就是说,io_service
和printf("3")
已经发布了!
总而言之,我相信你所寻找的是:
printf("4")