6

私は、OpenSSL、boost asio SSL 実装が基づいていることを知っていますが、同時 SSL_read() と SSL_write() (つまり、異なるスレッドによって実行される SSL_read() と SSL_write()) を許可しません。

同じスレッドから SSL ソケットで boost asio async_read() と async_write() を呼び出すのは安全ですか?

ありがとう

4

3 に答える 3

4

の要件boost::asio::ssl:::streamは、スレッド セーフのためです。どのスレッドが操作を開始できるかについての要件はありません。

個別のオブジェクト: 安全。

共有オブジェクト: 安全ではありません。また、アプリケーションは、すべての非同期操作が同じ暗黙的または明示的なストランド内で実行されるようにする必要があります。

io_serviceアプリケーションに、 およびasync_read()を処理するスレッドが 1 つしかない場合、async_write()そのスレッド内から開始された場合、操作および完了ハンドラが暗黙的なストランド内で実行されているため、安全です。

一方、複数のスレッドが を処理している場合io_serviceは、明示的strandが必要です。async_read()とのasync_write()操作は 内から開始する必要がstrandあり、完了ハンドラは同じ でラップする必要がありますstrand

Boost.Asio のスレッド セーフ要件、および合成操作の詳細については、この回答strandsを読むことを検討してください。

于 2013-08-23T22:25:51.113 に答える
3

同じスレッドからSSL ソケットを呼び出す ことは安全ですが、一般的に、ssl::stream での同時実行の問題を回避するには十分ではありません。実際の要件はドキュメントに記載されています:async_read()async_write()ssl::stream

スレッド セーフ (...) 共有オブジェクト: 安全ではありません。また、アプリケーションは、すべての非同期操作が同じ暗黙的または明示的なストランド内で実行されるようにする必要があります。

もちろん、次のことを保証するための標準的な boost::asio 要件:

  • async_readハンドラーが呼び出されるまで、他の読み取り操作は実行されません。
  • async_writeハンドラが呼び出されるまで、他の書き込み操作は実行されません。

も満たす必要があります。

書き込み操作の進行中に読み取り操作をスケジュールすることも、その逆も可能であることに注意してください。メカニズムssl::streamを介して OpenSSL のネットワーク ニーズを非同期に処理するおかげで、同時の非同期読み取りおよび書き込み操作が可能になります。また、エラー コードを返すことで通信の必要性を明らかにします。これらのエラー コードは、ネットワーク操作を非同期にスケジュールするために実装によって使用されます。の読み取りまたは書き込み操作では、基盤となるネットワーク ソケットで複数の読み取り操作と書き込み操作の両方が必要になる場合があり、 /への複数の呼び出しが必要になる場合があります。これは、非同期ネットワーク操作完了ハンドラーから (特に元の/からではなく) 実行されます。BIOSSL_read()SSL_write()SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITEssl::streamssl::streamSSL_read()SSL_write()async_readasync_writeasync_readこれが、とが同時に呼び出されないようにするだけでは不十分な理由ですasync_writeが、ストランドが必要です。

于 2013-08-23T20:47:16.157 に答える
1

安全。ただし、同じソケットでの 2 つ以上のasync_write-s のシミュレートは安全ではなく、セグメンテーション違反が頻繁に発生します (少なくとも SSL の場合)。

于 2013-08-23T20:24:52.170 に答える