2013-08-31 25 views
0

假設我有線程A和線程B.每個線程擁有同一對象的副本(爲簡單起見,我們稱它爲「Foo」)。 Foo中的某些數據片段在啓動時從文件初始化。所以這意味着在啓動時,我必須在Foo的兩個副本中設置從文件中讀取的數據。如果沒有從文件中讀取數據,那麼我仍然希望在兩個Foo副本中設置相同的數據實例,而不是每個線程分別初始化數據。C++ - 初始化不同線程擁有的對象的兩個副本

由於我正在使用的軟件的體系結構,我無法執行這項工作來構建任一副本的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中的兩個拷貝的數據乾淨的方式?謝謝!

+0

如果'm_Foo'確實是兩個線程之間的同一個實例,那麼它的'Initialize'不需要同步嗎? –

+0

對不起,我需要在那裏澄清。 m_Foo是線程Foo類的副本。由m_ThreadB.GetFoo()返回的Foo對象是線程B的Foo類的副本。 – Andrew

回答

0

我想你可能會因爲有線程而過度思考。如果沒有線程正在運行,那麼你可以使用任何你想要初始化它們的方法,因爲沒有比賽情況。甚至不要考慮線程。對於其餘的部分,我將調用ThreadA和threadB BugbearA和BugbearB。

如果您只有兩個Bugbear,並且BugbearA總是在BugbearB之前啓動,那麼您的解決方案是最好的解決方案。

如果情況實際上比你更加複雜,我建議重構數據以使共享對象包含可能從文件初始化的數據以及非共享對象對於每個Bugbear。 Start()的第一個Bugbear初始化共享對象。所有線程都將這些數據複製到他們自己的Foo中並開始。

如果您以後需要它,此重構也會爲您設置多線程。您所要做的就是爲共享對象提供適當的同步。