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.
}
线程安全,在g_lRunning
中直接阅读IsRunning()
并在g_lRunning
代码中使用InterlockedExchange
撰写Close()
吗?
如果我将f1
替换为f1_
,我会遇到问题,就像f1_
中的评论一样,你有什么更好的想法(不要在c中使用atom) ++ 11)
答案 0 :(得分:1)
关于问题1:
据我了解,直接读取g_lRunning是安全的。写入必须是原子的,因此对于每个写入操作都有一个InterlockedXXX
函数,但读取不需要是原子的,只有读取没有InterlockedXXX
函数。
在谈论线程安全时,您需要记住volatile不保证获取/释放语义,但在您的情况下,这应该不是问题。
关于问题2:
您也可以使用return ::InterlockedCompareExchange(&g_lRunning, 0, 0) == 1
。你可以用你喜欢的任何值替换两个零。
如果您可以使用C ++ 11,我建议您使用新的std::atomic
。
答案 1 :(得分:0)
看起来你正在创建一个SimpleSpinLock,所以值得注意的是,当你在while循环中运行时,你正在旋转并浪费CPU周期。如果您打算长时间旋转,内核模式锁定可能会更有效。