如果async_read套接字上有a ,则应该有一个内部线程来io_service检查套接字的状态.socket.close()从另一个线程调用是否安全(也许当它运行一个单独的处理程序时io_service)?
我的意思是即使我可以保证我的处理程序不会同时使用asio socket,它是否足够好(考虑内部线程时io_service)?
更新:
我正在使用async_read堆栈协程.与本文档底部的示例非常相似,只是我的有一个额外的函数层调用yield_context.如果我在该示例中调度socket.close()操作,my_strand整个事情是否安全?换句话说,所有相关的操作(堆栈协程的async_read中间async_read_some,隐式处理程序socket.close())是否会通过单个链运行my_strand?
Tan*_*ury 17
通常,对同一套接字对象1进行并发调用是不安全的.该async_read()构成的操作由零个或多个中间的async_read_some()操作.这些中间操作仅在当前正在调用的线程中启动io_service::run().内部线程相当透明,并且特定于平台的实现说明中列出的任何线程都不会出现问题.
因此:
io_service::run()并socket.close()从处理程序中调用,那么它是安全的,因为不可能并发执行.文档将此称为隐含链.io_service::run(),并socket.close()从处理程序之外调用,那么它是不安全的,因为socket可能有两个并发呼叫: close()从外部io_service和async_read_some()从当前调用线程io_service::run().要使其线程安全,请将处理程序发布到io_service调用中socket.close().io_service::run(),则需要显式链来保证线程安全.在async_read()从内发起的需求strand,而它的完成处理程序也必须包裹在同一条链.此外,socket.close()应通过钢绞线派遣.对于堆栈协程,使用spawn()接受a 的重载strand将在该上下文中执行提供的函数strand.此外,当yield_context对象作为处理程序传递给异步操作时,处理程序(包括来自组合操作的中间处理程序)在该上下文中被调用strand.因此,为确保线程安全,socket.close()必须:
在协程中调用:
// The lambda will execute within the context of my_strand.
boost::asio::spawn(my_strand,
[socket&](boost::asio::yield_context yield)
{
// In my_strand.
// ...
// The socket.async_read_some() operations that composed async_read()
// will run within the context of my_strand.
async_read(socket, ..., yield);
// Still within my_strand.
socket.close();
});
Run Code Online (Sandbox Code Playgroud)明确派发my_strand:
// The lambda will execute within the context of my_strand.
boost::asio::spawn(my_strand,
[socket&](boost::asio::yield_context yield)
{
// In my_strand.
// ...
// The socket_.async_read_some() operations that composed async_read()
// will run within the context of my_strand.
async_read(socket, ..., yield);
});
my_strand.dispatch([socket&](){ socket.close(); });
Run Code Online (Sandbox Code Playgroud)有关线程安全性,组合操作和线索的更多详细信息,请考虑阅读此答案.
1. 修订历史记录了此规则的异常.如果操作系统支持,则同步读取,写入,接受和连接操作是线程安全的.为了完整起见,我在这里包括它,但建议谨慎使用它.
| 归档时间: |
|
| 查看次数: |
2580 次 |
| 最近记录: |