6

I know that OpenSSL, boost asio SSL implementation is based on, doesn't allow concurrent SSL_read() and SSL_write() (i.e. SSL_read() and SSL_write() executed by different threads).

Is it safe to call boost asio async_read() and async_write() on SSL socket from the same thread?

Thanks

4

3 回答 3

4

的要求boost::asio::ssl:::stream是为了线程安全;它没有要求哪个线程可以启动操作:

不同的物体:安全。

共享对象:不安全。应用程序还必须确保所有异步操作都在相同的隐式或显式链中执行。

如果应用程序只有一个线程处理io_service, 和async_read()并且async_write()是从该线程内启动的,那么它是安全的,因为操作和完成处理程序在隐式链中运行。

另一方面,如果多个线程正在处理io_service,则需要显式strandasync_read()andasync_write()操作需要在 a 中启动,strand并且完成处理程序需要由相同的 包装strand

有关 Boost.Asio 的线程安全要求strands和组合操作的更多详细信息,请考虑阅读答案。

于 2013-08-23T22:25:51.113 回答
3

从同一个线程调用 async_read()和在 SSL 套接字上是安全的,但在一般情况下,避免 ssl::stream 的并发问题是不够的。文档中提供了实际要求:async_write()ssl::stream

线程安全 (...) 共享对象:不安全。应用程序还必须确保所有异步操作都在相同的隐式或显式链中执行。

当然,标准的 boost::asio 要求确保:

  • async_read在调用处理程序之前不会执行其他读取操作,并且
  • async_write在调用处理程序之前不会执行其他写入操作。

也必须满足。

请注意,允许在写操作正在进行时安排读操作,反之亦然。ssl::stream由于通过BIO机制异步处理OpenSSL的网络需求,可以同时进行异步读写操作。SSL_read()SSL_write()通过返回SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE错误代码来表达他们的沟通需求。这些错误代码被ssl::stream实现用来异步调度网络操作。上的读取或写入操作ssl::stream可能需要对底层网络套接字进行多次读取和写入操作以及对SSL_read()/的多次调用SSL_write(),这将由异步网络操作完成处理程序执行(特别是不是从原始async_read/async_writecall),这就是为什么仅仅确保async_readasync_write不被同时调用是不够的,而是需要一个链。

于 2013-08-23T20:47:16.157 回答
1

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

于 2013-08-23T20:24:52.170 回答