私は、OpenSSL、boost asio SSL 実装が基づいていることを知っていますが、同時 SSL_read() と SSL_write() (つまり、異なるスレッドによって実行される SSL_read() と SSL_write()) を許可しません。
同じスレッドから SSL ソケットで boost asio async_read() と async_write() を呼び出すのは安全ですか?
ありがとう
私は、OpenSSL、boost asio SSL 実装が基づいていることを知っていますが、同時 SSL_read() と SSL_write() (つまり、異なるスレッドによって実行される SSL_read() と SSL_write()) を許可しません。
同じスレッドから SSL ソケットで boost asio async_read() と async_write() を呼び出すのは安全ですか?
ありがとう
の要件boost::asio::ssl:::stream
は、スレッド セーフのためです。どのスレッドが操作を開始できるかについての要件はありません。
個別のオブジェクト: 安全。
共有オブジェクト: 安全ではありません。また、アプリケーションは、すべての非同期操作が同じ暗黙的または明示的なストランド内で実行されるようにする必要があります。
io_service
アプリケーションに、 およびasync_read()
を処理するスレッドが 1 つしかない場合、async_write()
そのスレッド内から開始された場合、操作および完了ハンドラが暗黙的なストランド内で実行されているため、安全です。
一方、複数のスレッドが を処理している場合io_service
は、明示的strand
が必要です。async_read()
とのasync_write()
操作は 内から開始する必要がstrand
あり、完了ハンドラは同じ でラップする必要がありますstrand
。
Boost.Asio のスレッド セーフ要件、および合成操作の詳細については、この回答strands
を読むことを検討してください。
同じスレッドからSSL ソケットを呼び出す ことは安全ですが、一般的に、ssl::stream での同時実行の問題を回避するには十分ではありません。実際の要件はドキュメントに記載されています:async_read()
async_write()
ssl::stream
スレッド セーフ (...) 共有オブジェクト: 安全ではありません。また、アプリケーションは、すべての非同期操作が同じ暗黙的または明示的なストランド内で実行されるようにする必要があります。
もちろん、次のことを保証するための標準的な boost::asio 要件:
async_read
ハンドラーが呼び出されるまで、他の読み取り操作は実行されません。async_write
ハンドラが呼び出されるまで、他の書き込み操作は実行されません。も満たす必要があります。
書き込み操作の進行中に読み取り操作をスケジュールすることも、その逆も可能であることに注意してください。メカニズムssl::stream
を介して OpenSSL のネットワーク ニーズを非同期に処理するおかげで、同時の非同期読み取りおよび書き込み操作が可能になります。また、エラー コードを返すことで通信の必要性を明らかにします。これらのエラー コードは、ネットワーク操作を非同期にスケジュールするために実装によって使用されます。の読み取りまたは書き込み操作では、基盤となるネットワーク ソケットで複数の読み取り操作と書き込み操作の両方が必要になる場合があり、 /への複数の呼び出しが必要になる場合があります。これは、非同期ネットワーク操作完了ハンドラーから (特に元の/からではなく) 実行されます。BIO
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 つ以上のasync_write
-s のシミュレートは安全ではなく、セグメンテーション違反が頻繁に発生します (少なくとも SSL の場合)。