我知道OpenSSL,boost asio SSL实现是基于的,不允许并发SSL_read()和SSL_write()(即不同线程执行的SSL_read()和SSL_write())。
从同一个线程调用SSL套接字上的boost asio async_read()和async_write()是否安全?
由于
答案 0 :(得分:4)
boost::asio::ssl:::stream
的要求是线程安全;它没有要求哪个线程可以启动操作:
不同的物体:安全。
共享对象:不安全。应用程序还必须确保所有异步操作都在同一个隐式或显式链中执行。
如果应用程序只有一个线程处理io_service
,并且async_read()
和async_write()
是从该线程内启动的,则它是安全的,作为操作和完成处理程序(s )正在隐含的链中运行。
另一方面,如果多个线程正在处理io_service
,则需要显式strand
。需要在async_read()
内启动async_write()
和strand
操作,并且完成处理程序需要由相同的strand
包装。
有关Boost.Asio的线程安全要求,strands
和撰写的操作的更多详细信息,请考虑阅读this answer。
答案 1 :(得分:3)
从同一个线程在SSL套接字上调用 async_read()
和async_write()
是安全的,但在一般情况下它是不够的到避免使用ssl :: stream的并发问题。实际要求在ssl::stream
documentation:
线程安全(...)共享对象:不安全。应用程序还必须确保所有异步操作都在同一个隐式或显式链中执行。
当然,标准的boost :: asio要求确保:
async_read
处理程序获取之前,不执行任何其他读取操作
叫,和async_write
处理程序之前,不会执行任何其他写操作。也必须得到满足。
注意,允许在写操作正在进行时安排读操作,反之亦然。由于通过BIO
机制异步处理OpenSSL的网络需求,ssl::stream
可以同时进行异步读写操作。 SSL_read()
和SSL_write()
通过返回SSL_ERROR_WANT_READ
和SSL_ERROR_WANT_WRITE
错误代码来表明他们的沟通需求。 ssl::stream
实现使用这些错误代码来异步调度网络操作。对ssl::stream
的读取或写入操作可能需要对底层网络套接字进行多次读取和写入操作,以及对SSL_read()
/ SSL_write()
进行多次调用,这将从异步网络操作完成处理程序执行(特别是不是来自最初的async_read
/ async_write
来电),这就是为什么不能确保async_read
和async_write
不会被同时调用,而是一个链是需要的。
答案 2 :(得分:1)
很安全。但是在同一个套接字上模拟2个或更多async_write
- s是不安全的并且经常会出现段错误(至少对于SSL情况而言)。