【发布时间】:2009-06-17 21:46:09
【问题描述】:
对What's wrong with this fix for double checked locking? 的评论说:
问题是变量可能是 在构造函数运行之前分配 (或完成),而不是在对象之前 已分配。
让我们考虑代码:
A *a;
void Test()
{
a = new A;
}
为了进行更正式的分析,让我们将 a = new A 拆分为几个操作:
void *mem = malloc(sizeof(A)); // Allocation
new(mem) A; // Constructor
a = reinterpret_cast<A *>(mem); // Assignment
上面引用的评论是否属实,如果属实,在什么意义上?构造函数可以在赋值之后执行吗?如果可以,由于 MT 安全需要保证订单时,可以采取什么措施?
【问题讨论】:
-
没有什么可以对付它,真的。您将必须使任何读取和任何写入变得易失,并且必须使“内存”也变得易失,以保持代码写入的顺序,并让所有这些写入/读取由序列点分隔。但这仍然不会对多线程做任何事情:标准对此一无所知。
-
如“int volatile a, b; a = 1; b = 2;”这两个不能重新排序,并且在“int volatile a; int b; a = 1; b = 2;”中那么这些 can 可以重新排序,因为 b 不是易变的。而在 f(a=1, b=2);然后这些也可以“重新排序”,因为一开始就没有任何顺序。我发现 alexandrescu 和 scott meyers 的文章很好地解释了这一点,恕我直言
-
见:常见的未定义行为stackoverflow.com/questions/367633/…
标签: c++ multithreading constructor multicore sequence-points