从一个线程中提升asio - SSL async_read和async_write

时间:2013-08-23 18:28:46

标签: c++ boost ssl openssl boost-asio

我知道OpenSSL,boost asio SSL实现是基于的,不允许并发SSL_read()和SSL_write()(即不同线程执行的SSL_read()和SSL_write())。

从同一个线程调用SSL套接字上的boost asio async_read()和async_write()是否安全?

由于

3 个答案:

答案 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_READSSL_ERROR_WANT_WRITE错误代码来表明他们的沟通需求。 ssl::stream实现使用这些错误代码来异步调度网络操作。对ssl::stream的读取或写入操作可能需要对底层网络套接字进行多次读取和写入操作,以及对SSL_read() / SSL_write()进行多次调用,这将从异步网络操作完成处理程序执行(特别是不是来自最初的async_read / async_write来电),这就是为什么不能确保async_readasync_write不会被同时调用,而是一个链是需要的。

答案 2 :(得分:1)

很安全。但是在同一个套接字上模拟2个或更多async_write - s是不安全的并且经常会出现段错误(至少对于SSL情况而言)。