サーバー上の共有 STL C++ リストを変更する要求を受け入れる複数の prefork サーバー プロセスがあります。各プロセスは、単純にリストの最後に新しい要素をプッシュし、反復子を返します。
各プロセスがリストのロックを取得する方法がわかりません。オブジェクト全体にする必要がありますか、それともリストの最後に要素をプッシュしているだけなので、STL リストは同時実行を処理できますか?
サーバー上の共有 STL C++ リストを変更する要求を受け入れる複数の prefork サーバー プロセスがあります。各プロセスは、単純にリストの最後に新しい要素をプッシュし、反復子を返します。
各プロセスがリストのロックを取得する方法がわかりません。オブジェクト全体にする必要がありますか、それともリストの最後に要素をプッシュしているだけなので、STL リストは同時実行を処理できますか?
プロセスではなくスレッドを意味していると仮定すると、STL コンテナーを共有できますが、同期に関して注意する必要があります。STL コンテナーはある程度スレッド セーフですが、次のようなスレッド セーフの保証を理解する必要があります。
これらの制限の理由は、コンテナーのインターフェイスが 1 つのスレッド内で効率的に使用されるように調整されており、スレッド間で共有される可能性がある共有されていないコンテナーの処理を妨げたくないためです。また、コンテナー インターフェイスは、コンテナーが維持する同時実行メカニズムには適していません。たとえば、v.empty()
返さfalse
れたからといって、コンテナが空になる可能性があるため、機能するとは限りませんv.pop()
。内部同期があった場合、返された時点でロックが解放され、呼び出されるempty()
までにコンテナを変更できます。pop()
異なるスレッド間の通信に使用するキューを作成するのは比較的簡単です。std::mutex
と の適切なインスタンス化を使用しますstd::condition_variable
。標準に含めるために提案されたこのようなものがあると思いますが、まだ標準 C++ ライブラリの一部ではありません。ただし、そのようなクラスは、挿入された要素にイテレータを返さないことに注意してください。これは、アクセスするまでに、要素が再びなくなっている可能性があり、とにかくイテレータが何に使用されているかが疑わしいためです。
複数のプロセス間でこの種の同期を行うためのメカニズムでは、開発者がいくつかの問題に対処する必要があります。まず、プロセス間で共有されるものはすべて、それらの外部で設定する必要があります。これが通常実際に意味することは、 の使用ですshared memory
。
次に、これらのプロセスは、共有されているメモリへのアクセスに関して相互に通信する必要があります。結局のところ、1 つのスレッドが共有されているデータ構造で作業を開始しても、操作が完了する前にスワップアウトされると、データの一貫性が失われます。
この同期は、Linux のセマフォなどのオペレーティング システム構造を使用して行うことができ、競合するプロセスを調整できます。
Linux ベースの IPC の詳細については、これを参照して くださいWindows ベースの IPC の詳細については、これを参照してください
参考のために、プラットフォームに依存しない IPC メカニズムの実装を提供するBoost.Interprocess
ドキュメントを使用できます。
標準ライブラリ コンテナーは、同時変更に対する自動保護を提供しないため、キューへのアクセスごとにグローバル ロックが必要です。
対応する要素がいつリストから削除されたかを必ずしも知っているとは限らないため、リスト要素への反復子または参照にも注意する必要があります。