我目前正在尝试使用 Boost::Asio 创建一个服务器应用程序,该应用程序执行两个简单的操作:
boost::asio::deadline_timer重复的过程以下代码显示了我当前的尝试:
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <WinSock2.h>
#include <Mswsock.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::asio;
using namespace boost::asio::ip;
void timerHandler(const boost::system::error_code& errorCode, deadline_timer* timer) {
timer->expires_at(timer->expires_at() + boost::posix_time::seconds(1));
timer->async_wait(boost::bind(timerHandler, _1, timer));
}
void acceptHandler(const boost::system::error_code &errorCode, io_service *ioService) {
deadline_timer timer(*ioService, boost::posix_time::seconds(1));
timer.async_wait(boost::bind(timerHandler, _1, &timer));
}
int main(int argc, char** argv) {
io_service ioService;
tcp::socket socket(ioService);
tcp::acceptor acceptor{ ioService, tcp::endpoint{ tcp::v4(), 12345 } };
acceptor.listen();
acceptor.async_accept(socket, boost::bind(acceptHandler, _1, &ioService));
ioService.run();
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
问题:
计时器在某种程度上无法按预期工作acceptHandler。不知何故,它被取消了两次,触发了一个错误,并最终导致整个应用程序崩溃。
处理程序跟踪输出:
@asio|1460922050.075890|0*1|socket@000000000015FAD0.async_accept
@asio|1460922051.153952|>1|ec=system:0
@asio|1460922051.153952|1*2|deadline_timer@000000000015F608.async_wait
@asio|1460922051.153952|1|deadline_timer@000000000015F608.cancel
@asio|1460922051.153952|<1|
@asio|1460922051.153952|>2|ec=system:995
@asio|1460922051.153952|2|deadline_timer@000000000015F608.cancel
Run Code Online (Sandbox Code Playgroud)
问题:
acceptHandler取消 Handler Tracking 输出第 4 行中的 Deadline_timer?是什么导致 Handler Tracking 输出第 6 行出现错误 995?错误消息是:由于线程退出或应用程序请求,I/O 操作已中止
是什么导致timerHandler取消Handler Tracking输出第7行中的deadline_timer?
timer分配在堆栈上,因此在调用acceptHandler时无效。timerHandler您需要动态分配计时器。
另外,您应该检查两个处理程序中的错误代码。当您想要结束程序和cancel计时器时,这一点尤其重要。