マルチスレッド環境で使用される複雑なデータ構造へのアクセスを制御するコンテナクラスを作成することを考えていました。
そして、質問が私に起こりました:
C ++コンストラクターがスレッドセーフでなければならない状況はありますか?
マルチスレッド環境で使用される複雑なデータ構造へのアクセスを制御するコンテナクラスを作成することを考えていました。
そして、質問が私に起こりました:
C ++コンストラクターがスレッドセーフでなければならない状況はありますか?
一般に、 2 つのスレッドが同時に同じオブジェクトに対してコンストラクターを呼び出すことはできません。ただし、同じコンストラクターを異なるオブジェクトに対して同時に呼び出すことはできます。
確かに、一度に複数のスレッドから同じコンストラクターを呼び出すことができます。その意味で、他の関数と同じように、スレッドセーフである必要があります。コンストラクターが共有状態(コンテナーなど)を変更する場合は、同期を使用して、状態が決定論的な方法で変更されるようにする必要があります。
各オブジェクトは一度だけ構築されるため、一度に複数のスレッドで同じオブジェクトを構築することはできません。したがって、同じオブジェクトでコンストラクターを複数回呼び出す方法はありません。同時に2つの異なるスレッドでコンストラクターを呼び出すことはできません。 。
私の経験ではありません。コンストラクターを呼び出すコードは、暗黙的または別の方法で、アプリケーションが必要とする場合にスレッドセーフにする必要があります。
理論的根拠は、一度に 1 つのスレッドのみがオブジェクトを初期化する必要があるため、コンストラクター自体内で初期化されるオブジェクトを保護するために同期は必要ないということです (オブジェクトの初期化が完了していない場合は、とにかくスレッド間で共有されるべきではありません)。 )。
別の見方をすると、オブジェクトは、コンストラクターが戻るまで、論理的に存在しないものとして扱われます。したがって、オブジェクトを作成中のスレッドは、そのオブジェクトについて「認識」している唯一のスレッドです。
もちろん、適切な同期規則は、コンストラクター自体がアクセスするすべての共有リソースに適用されますが、それはすべての関数に適用されます (コンストラクターは特別であり、何らかの方法ですべてのリソースへの排他的アクセスを提供すると信じて、これを理解していない人に遭遇しました)。