假设我有线程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的两个副本中初始化数据的最简洁方法吗?谢谢!
答案 0 :(得分:0)
我认为你可能会过度思考它,因为有线程。如果没有正在运行的线程,那么您可以使用任何您希望初始化它们的方法,因为没有竞争情况。甚至不要考虑线程。对于其余部分,我将调用ThreadA和threadB BugbearA和BugbearB。
如果你只有两个Bugbears,并且BugbearA总是在BugbearB之前启动,那么你的解决方案是最好的解决方案。
如果情况实际上比您允许的情况更复杂,我建议重构数据以使共享对象包含可以从文件初始化的数据,以及非共享对象对于每个Bugbear。第一个Bugbear to Start()初始化共享对象。所有线程都将这些数据复制到自己的Foo中并开始。
如果您以后需要,这个重构器还会为多线程设置。您所要做的就是为共享对象提供适当的同步。