假设我有一个简单的A类,在C ++中有一个字段。该字段在构造函数中初始化。 A类还有一个名为doit()
的方法,用于修改该字段的值。将从多个线程调用doit()
。如果我只在doit()
方法中使用互斥锁,这是否足够?我是否保证永远不会读取未初始化的字段(因为构造函数中没有锁定)?
编辑:我可能不太清楚。是否没有涉及处理器缓存或类似问题的问题?我的意思是,如果没有用于初始化内存区域的互斥锁(即我的字段) - 是否存在其他线程读取某些垃圾值的风险?
答案 0 :(得分:7)
您的对象只能初始化一次,并且在初始化之前您将无法使用它,因此您不需要在那里使用互斥锁。但是,您需要在DoIt
函数中使用互斥锁或其他合适的锁,正如您所说,这将在多个线程中访问。
已修改问题的更新:不,您无需担心处理器缓存。在获得对象之前,必须先构造对象。只有拥有此句柄后,才能将其传递给其他要使用的线程。我想说的是,产生的线程必须在原始对象构造之后才开始,它不可能以相反的方式发生!
答案 1 :(得分:2)
无法在尚未创建的对象上调用doit()
,因此构造函数中不需要互斥锁。
如果doit()
是访问该字段的唯一方法,那么您应该没问题。
如果您的类的其他方法也访问该字段,即使是从单个线程,也必须在这些方法中使用互斥锁。
答案 2 :(得分:0)
或者,如果您了解各种方法与各种算法的交互,您可以使用互斥量来代替使用该字段的critical sections代码 - 即代码的一部分需要确保该字段是在处理过程中没有被另一个线程改变,但你的方法可以在关键部分之后释放锁定,做其他事情然后可能有另一个关键部分。