C++-初始化由不同线程拥有的对象的两个副本

C++ - Initialize 2 copies of object owned by different threads

本文关键字:副本 两个 对象 C++- 线程 拥有 初始化      更新时间:2023-10-16

假设我有线程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的两个副本中的数据的最干净的方法吗?谢谢

我想你可能想得太多了,因为有线程。如果没有线程在运行,那么您可以使用任何希望初始化它们的方法,因为不存在争用情况。甚至不要考虑线程。对于剩下的部分,我将调用ThreadA和threadB BugbearA和BugbearB。

如果你只有两个Bugbear,而BugbearA总是在BugbearB之前开始,那么你的解决方案是有史以来最好的。

如果情况实际上比您所说的更复杂,我建议重构数据,使其具有一个包含可能从文件初始化的数据的共享对象,以及一个为每个Bugbear共享的对象。第一个Bugbear to Start()初始化共享对象。所有线程都将该数据复制到自己的Foo中并启动。

如果以后需要的话,这个重构还会为您设置多线程。您所要做的就是为共享对象提供适当的同步。