volatile LONG g_lRunning = 1;
bool IsRunningEx()
{
return ::InterlockedExchange(&g_lRunning, 1) == 1;
}
bool IsRunning()
{
return g_lRunning == 1;
}
void Close()
{
::InterlockedExchange(&g_lRunning, FALSE);
}
void f1()
{
while (IsRunning())
{
// do some thing
}
}
void f2()
{
Close();
}
int _tmain(int argc, _TCHAR* argv[])
{
std::thread t1(f1);
std::thread t2(f2);
t1.detach();
t2.detach();
return 0;
}
void f1_()
{
while (IsRunningEx())
{
// do some thing
}
::InterlockedExchange(&g_lRunning, FALSE);
// I must do some thing like this in here or in IsRunningEx internal,
// because after calling IsRunningEx() g_lRunning will be TRUE.
// So when call IsRunningEx() next time, it will return TURE,
// but it would return FALSE in hope.
}
是否线程安全,直接在IsRunning()
中读取g_lRunning
,使用InterlockedExchange
写入g_lRunning
> 在 Close()
上面的代码中?
如果我把f1
替换成f1_
,我会遇到一个问题,就像f1_
中的注释一样,你有没有更好的idea(不要在c++11中使用atom)
关于问题1:
据我了解,直接读取 g_lRunning 是安全的。写入必须是原子的,因此对于每个写入操作都有一个 InterlockedXXX
函数,但读取不需要是原子的并且没有 InterlockedXXX
函数只用于读取.
在谈论线程安全时,您需要记住,volatile 不能保证获取/释放语义,但在您的情况下,这应该不是问题。
关于问题2:
您还可以使用 return::InterlockedCompareExchange(&g_lRunning, 0, 0) == 1
。您可以用您喜欢的任何值替换这两个零。
如果您可以使用 C++11,我真的建议您使用新的 std::atomic
。
我是一名优秀的程序员,十分优秀!