Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 线程安全地关闭正在同步使用的boost::asio::ip::tcp::socket_C++_Boost_Boost Asio - Fatal编程技术网

C++ 线程安全地关闭正在同步使用的boost::asio::ip::tcp::socket

C++ 线程安全地关闭正在同步使用的boost::asio::ip::tcp::socket,c++,boost,boost-asio,C++,Boost,Boost Asio,考虑到boost::asio::ip::tcp::acceptor和boost::asio::ip::tcp::socket在boost 1.52.0中都被标记为非线程安全的,是否可以关闭当前在从单独线程接收时阻塞的tcp::acceptor 我已经研究了调用boost::asio::io_服务::stop,这看起来是可能的,因为io_服务是线程安全的。这会使io_服务事件循环一直运行,直到套接字上的任何处理完成吗 我是同步操作的,因为这是作为更大程序的一部分的简单事件循环,我不想在没有充分理由

考虑到boost::asio::ip::tcp::acceptor和boost::asio::ip::tcp::socket在boost 1.52.0中都被标记为非线程安全的,是否可以关闭当前在从单独线程接收时阻塞的tcp::acceptor

我已经研究了调用boost::asio::io_服务::stop,这看起来是可能的,因为io_服务是线程安全的。这会使io_服务事件循环一直运行,直到套接字上的任何处理完成吗

我是同步操作的,因为这是作为更大程序的一部分的简单事件循环,我不想在没有充分理由的情况下创建额外的线程,我理解异步可以做到这一点。

如果您的接收器处于async\u accept中,您可以调用ip::tcp::acceptor::cancel来取消对它的任何异步操作。注意,这可能会使用boost::asio::error::operation\u中止的错误代码在此接受程序中启动处理程序


如果您使用的是同步接受,这似乎是不可能的,因为我认为它与io_服务完全无关。

花了一些时间来研究这一点,只有一种线程安全的方式可以实现这一点:通过向未等待接受的线程上的套接字发送消息,告诉线程关闭套接字和接受程序。通过这样做,套接字和接收器可以完全由单个线程拥有


正如另外指出的,io_服务只用于异步操作。

我认为您考虑了一下这一点。在条件循环中使用带超时的非阻塞接受或本机接受。添加互斥锁,它是线程安全的。当新连接到达时,您还可以使用本机选择并接受。为select设置超时和条件循环。

为什么需要从单独的线程调用stop?ASIO背后的全部要点是应用程序是单线程的。理想情况下,其中一个事件触发器回调将调用stop。@chrisayock ASIO背后的全部要点是应用程序是单线程的。-这完全不是真的。io_服务分派处理程序,停止它对您没有帮助。另一方面,从另一个线程关闭接受程序不是线程安全的。唯一安全的方法是使用async_accept,然后在需要时从同一线程关闭该接受程序。@PSIAlt而不需要。因为它不是必需的,所以可以从盒子中使用。许多线程可以运行io_service::run,并且处理程序将被分派到所有这些线程,因此您很容易获得异步多线程。此外,还有许多东西可以简化asio的多线程处理,比如asio::strand etcPrefer close,因为cancel的可移植性不够,可能会带来麻烦。请参阅下面的文章,它讨论套接字,但也适用于acceptor。@PSAIT我认为有一个解决方案,我已经在回答中概述了这个解决方案。如果你看了一眼,觉得我错了,就告诉我。@IgorR。谢谢,我不知道这个windows限制,我只在unixWell上写,这应该有助于阻止这种情况。看起来像一个黑客,但如果你喜欢这个,okI得出了同样的结论。很遗憾,同步接受没有以某种方式取消,就像同步读取/读取一样。我使用了同步调用,因为这是为了简单使用而推荐的,但是现在我遇到了这个问题,我必须重写所有内容。我觉得同步调用应该被阻止,因为这一个调用。