繁体   English   中英

中断boost :: asio同步读取?

[英]Interrupt boost::asio synchronous read?

我正在使用asio同步套接字从后台线程通过TCP读取数据。 这封装在“服务器”类中。

但是,我希望线程在调用此类的析构函数时退出。 问题是对任何读取函数的调用都会阻塞,因此线程不能轻易终止。 在Win32中有一个API: WaitForMultipleObjects ,它将完全符合我的要求。

如何通过提升获得类似的效果?

在我们的应用程序中,我们设置“终止”条件,然后使用自连接到线程正在侦听的端口,以便它唤醒,注意终止条件并终止。

您还可以检查boost实现 - 如果它们只对套接字进行简单读取(即,不在内部使用WaitForMultipleObjects之类的东西),那么您可能会得出结论,没有任何东西可以简单而干净地解除阻塞。 如果他们在等待多个对象(或完成端口),你可以挖掘周围以查看唤醒阻塞线程的能力是否暴露在外面。

最后,你可以杀死线程 - 但你必须超出提升才能做到这一点,并了解后果,例如悬空或泄漏的资源。 如果您正在关闭,这可能不是一个问题,取决于该线程正在做什么。

我发现没有简单的方法可以做到这一点。 据说,有办法取消win32 IOCP,但它在Windows XP上运行不佳。 MS确实为Windows Vista和7修复了它。取消asio async_readasync_write的推荐方法是关闭套接字。

  • [析构者]请注意我们要拆解
  • [析构函数]关闭套接字
  • [析构函数]等待完成处理程序

  • [完成]如果拆除并且我们因套接字关闭而失败,通知析构函数完成处理程序已完成。

  • [完成]立即返回。

如果您选择实施此操作,请务必小心。 关闭套接字非常简单。 “等待完成处理程序”然而却是巨大的不足。 当服务器的线程及其析构函数交互时,可能会出现一些细微的角落情况和竞争条件。

这非常微妙,我们构建了一个完成包装器(类似于io_service::strand只是为了同步取消所有挂起的完成回调。

最好的方法是创建一个socketpair() ,(无论是在boost::asio用语中),将读取器端添加到事件循环中,然后关闭socketpair()器端。 您将立即在该套接字上使用eof事件唤醒。

然后线程必须自愿关闭自己。

线程的产生者应该在它的析构函数中,具有以下内容:

~object()
{
    shutdown_queue.shutdown();   // ask thread to shut down
    thread.join();               // wait until it does
}
boost::system::error_code _error_code;
client_socket_->shutdown(client_socket_->shutdown_both, _error_code);

上面的代码帮助我立即关闭同步读取。

使用socket.cancel(); 结束在套接字上阻塞的所有当前异步操作。 客户端套接字可能需要在循环中被杀死。 我从来没有以这种方式关闭服务器,但你可以使用shared_from_this()并在循环中运行cancel()/ close(),类似于boost聊天示例async_writes到所有客户端的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM