7

私はたくさんのスレッドを持っています。シングルトンの作成時に一度初期化される構成データを含むシングルトンにアクセスする必要があります。したがって、最初のアクセスで。そのため、シングルトンでの以降のアクションは読み取り専用です。この場合、クリティカル セクションは必要ですか?

4

5 に答える 5

6

データは最初のアクセスで遅延して作成されるため、シングルトンへのポインターまたは参照は読み書き可能です。これは、クリティカル セクションが必要であることを意味します。

実際、このような状況で遅延初期化を維持しながらクリティカル セクションを回避したいという欲求は、非常に普遍的に強く、ダブルチェック ロック アンチパターンの作成につながっています。

一方、読み取りの前にシングルトンを熱心に初期化する場合は、定数ポインター/参照を介して不変オブジェクトにアクセスするためのクリティカル セクションを回避できます。

于 2012-11-14T20:18:43.207 に答える
1

あなたのシングルトンには遅延初期化があるので、あなたの質問を理解しています。最初の読み取り時のみ初期化されます。

次の連続した読み取りはスレッドセーフです。しかし、初期化中の同時読み取りについてはどうでしょうか。

このような状況がある場合:

SomeConfig& SomeConfig::getInstance()
{
   static SomeConfig instance;
   return instance;
} 

次に、コンパイラに依存します。C++03 のこの投稿によると、この静的初期化がスレッド セーフであるかどうかは実装に依存していました。

C++11 の場合、スレッド セーフです。この投稿への回答、引用を参照してください。

このような変数は、コントロールがその宣言を最初に通過するときに初期化されます。そのような変数は、初期化の完了時に初期化されたと見なされます。[...]変数の初期化中に制御が同時に宣言に入ると、同時実行は初期化の完了を待機します。

グローバル変数への読み取り専用アクセスはスレッドセーフであることに注意してください。

于 2012-11-14T20:25:28.823 に答える
0

いいえ。完全に初期化された後にこのデータを読み取るだけで、データが変更されない場合は、競合状態が発生する可能性はありません。

ただし、データが何らかの方法で書き込まれたり変更されたりする場合は、データへのアクセスを同期する必要があります。つまり、書き込む前にデータをロックします。

于 2012-11-14T20:16:21.930 に答える
0

共有データを読み取るだけで書き込みを行わない場合は、アクセスを同期する必要はありません。

共有データの読み取りと書き込みが同時に行われる可能性がある場合にのみ、同期する必要があります。

于 2012-11-14T20:17:01.863 に答える