假设我们有这个简单的类:
class example
{
bool m_isCanceled;
example() : m_isCanceled(false) {}
public:
void cancel() { m_isCanceled = true; }
void doWork()
{
for (int i = 0; i < MAX_RETRIES; ++i)
{
// Slow
doStuff();
if (m_isCanceled)
{
return;
}
}
}
}
如果我们在一个线程上调用example::doWork()
,然后在一段时间后我们在另一个线程上调用example::cancel()
,那么在第一个线程看到m_isCanceled
之前有多长时间的约束现在是真的吗?
在类似的情况下,我建议我们使用互斥锁保护m_isCanceled,但我的同事说第一个线程最多会在额外的迭代后看到更新。这是对的吗?
答案 0 :(得分:3)
根本没有保证。理想情况下,您可以将布尔变量设为原子。如果做不到这一点,那么volatile
恰好可以在几乎所有已知平台上运行。当然,使用互斥锁保护它可以保证正常工作。
在实践中,无论如何它都会“碰巧工作”。实现通常不知道doStuff
或它调用的某个函数是否操纵m_isCancelled
。因此,它无法将其保存在寄存器或其他内容中。