0

スレッド A とスレッド B があるとします。各スレッドは同じオブジェクトのコピーを所有しています (簡単にするために「Foo」と呼びましょう)。Foo 内の特定のデータは、起動時にファイルから初期化されます。つまり、起動時に、ファイルから読み取ったデータを Foo の両方のコピーに設定する必要があります。ファイルからデータが読み取られない場合でも、Foo の両方のコピーに同じデータ インスタンスを設定し、各スレッドでデータを個別に初期化しないようにします。

私が取り組んでいるソフトウェアのアーキテクチャが原因で、Foo のいずれかのコピーの構築でこの作業を実行できません。そのため、オブジェクトの構築後に呼び出される Initialize() または同様のメソッドを実行する必要があります。これはすべてアプリケーションの初期化段階で行われるため、スレッド セーフについて心配する必要はありませんが、このソリューションのクリーン度については懸念があります。これが私がこれまでに思いついたものです:

ThreadA::Start()
{
    ...

    // Initialize() will read the data from the file if it exists. Otherwise, it will set default values.
    m_Foo.Initialize();

    // Now call Initialize() for thread B's copy of Foo while running in thread A but before thread B is even started. Pass in thread A's copy of Foo to set the values with. This should be safe to do since thread B has not even started yet.
    m_ThreadB.GetFoo().Initialize(m_Foo);

    ...
}

これは、Foo の両方のコピーでデータを初期化する最もクリーンな方法ですか? ありがとう!

4

1 に答える 1

0

スレがあるから考え過ぎなのかな。スレッドが実行されていない場合は、競合ケースがないため、スレッドを初期化する任意の方法を使用できます。スレッドについても考えないでください。これ以降は、代わりに ThreadA と threadB を BugbearA と BugbearB と呼びます。

Bugbear が 2 つしかなく、BugbearA が常に BugbearB の前に開始される場合、あなたの解決策はこれまでに考えられた中で最高のものです。

状況が実際よりも複雑な場合は、データをリファクタリングして、ファイルから初期化できるデータを含む共有オブジェクトと、Bugbear ごとに非共有オブジェクトを作成することをお勧めします。Start() に対する最初の Bugbear は、共有オブジェクトを初期化します。すべてのスレッドは、そのデータを独自の Foo にコピーして開始します。

このリファクタリングは、後で必要になった場合にマルチスレッドの設定も行います。必要なのは、共有オブジェクトに適切な同期を提供することだけです。

于 2013-09-01T04:44:52.133 に答える