17

私が持っているとしましょう:

stl::map<std::string, Foo> myMap;

次の関数スレッドは安全ですか?

myMap["xyz"] ?

つまり、多くのスレッド間で共有されるこの巨大な読み取り専用マップが必要です。しかし、それを検索してもスレッドセーフかどうかはわかりません。


すべてが最初に一度書き込まれます。

その後、複数のスレッドがそこから読み取ります。

私はこれをできるだけ速くするためにロックを避けようとしています。(私が知っているヤヤの可能性のある時期尚早の最適化)

4

5 に答える 5

16

C++11 ではconst、複数のリーダーに対してスレッドセーフとして宣言されたすべてのメンバー関数が必要です。

として宣言されていないため、呼び出しmyMap["xyz"]はスレッドセーフではありません。ただし、 として宣言されているため、呼び出しはスレッドセーフです。std::map::operator[]constmyMap.at("xyz")std::map::atconst

于 2013-05-04T11:26:07.683 に答える
11

理論的には、スレッドセーフなSTLコンテナはありません。実際には、コンテナが同時に変更されていない場合、読み取りは安全です。つまり、標準ではスレッドに関する仕様は作成されていません。標準の次のバージョンとIIUCは、安全な読み取り専用の動作を保証します。

本当に心配な場合は、二分探索でソートされた配列を使用してください。

于 2010-01-31T04:41:59.047 に答える
6

少なくともMicrosoftの実装では、コンテナーからの読み取りはスレッドセーフです(参照)。

ただし、std::map::operator[]データを変更でき、宣言されていませんconst。代わりに、を使用std::map::findしてconst、を取得し、const_iteratorそれを逆参照する必要があります。

于 2010-01-31T04:42:51.990 に答える
4

理論的には、読み取り専用のデータ構造と関数は、スレッド セーフのためのロックを必要としません。本質的にスレッドセーフです。同時メモリ読み取りでデータ競合はありません。ただし、単一のスレッドのみによる安全な初期化を保証する必要があります。

Max S. が指摘したように、ほとんどの場合、マップ内の要素を読み取る実装にはmyMap["xyz"]、書き込み操作はありません。もしそうなら、それは安全です。ただし、ここでも、初期化フェーズ以外の構造を変更するスレッドがないことを保証する必要があります。

于 2010-01-31T05:00:01.983 に答える
1

STLコレクションはスレッドセーフではありませんが、スレッドセーフを追加するのはかなり簡単です。

最善の策は、問題のコレクションの周りにスレッドセーフなラッパーを作成することです。

于 2010-01-31T04:31:38.583 に答える