在下面的代码片段中,当某个值发生变化时,一个线程会调用SetValue(),而另一个线程则会调用GetValue()来检索该值。我的问题是,在任何情况下,GetValue()都会返回一个虚假的结果吗?
double g_value[2];
// Thread one calls this to set the value
void SetValue( double value )
{
g_value[0] = value;
g_value[1] = value;
}
// Thread two calls this to get the value
double GetValue()
{
double value[2];
do
{
value[0] = g_value[0];
value[1] = g_value[1];
}
while ( value[0] != value[1] );
return value[0];
}
C标准不能保证这会产生合理的结果。正如您所写的,当编译器认为它知道全局变量的最后一个存储值时,它甚至可能会受到优化。
但是,即使您声明了全局变量volatile
,您也可能会感到意外。比较的结果取决于缓存线、缓存一致性、部分加载以及许多您无法轻松控制的事情。此外,结果完全依赖于体系结构。
现代C,也就是C11,具有用于您想要实现的任务的_Atomic
,并且所有现代处理器都支持原子功能。使用这些,或者通过互斥锁、读写锁或类似的方式来保护您的变量。
如果您对无锁线程感兴趣,那么您可以查看此链接。然而,请详细介绍它预先定义的假设——这对实现非常重要。