这个函数的命名看起来像是一些复杂的事情。到底什么时候人们才知道这是正确的方法,而不是做这样的事情:

准备CRITICAL_SECTION cs;int *p = malloc(sizeof(int));//分配站点初始化智力(&cs);// 第一次写入的提示

话题#1{ *p = 1;//首先写}

话题#2{enterCriticalSection(&cs);*p = 2;//第二次写leavecricitysection(&cs);}

我有一个在一个线程中完成的写入:

Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}

然后,我在另一个线程中完成读取(可能同时):

Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}

解决这种竞争状况的最佳解决方案是什么?临界区是可行的方法还是使用 InterlockedExchangeAdd() 更有用?

有帮助吗?

解决方案

InterlockedExchangeAdd 用于将值作为原子操作添加到整数,这意味着您不必使用临界区。如果您的一个线程抛出异常,这也消除了死锁的风险 - 您需要确保不保留任何类型的锁,因为这会阻止其他线程获取该锁。

对于您的场景,您绝对可以使用 Interlocked...- 函数,但我会使用事件(CreateEvent、SetEvent、WaitForSingleObject),可能是因为我经常发现自己需要等待多个对象(您可以等待零秒)在你的场景中)。

更新:对变量使用 volatile 可能有效,但不建议这样做,请参阅: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.htmlhttp://www-949.ibm.com/software/rational/cafe/blogs/ccpp-parallel-multicore/tags/c%2B%2B0x 例如。

如果你想便携,请看一下 提升::线程.

其他提示

在你的情况,有没有竞争条件。该变量从未被重置为FALSE,是吗?这对线程只是一个“请死”的开关,对不对?然后不需要任何种类的同步。

在InterlockedXXX系列函数利用英特尔CPU的原子三操作数命令(XADD和CMPXCNG)的。所以,他们比临界区要便宜得多。你想为线程安全的任务之一是InterlockedCompareExchange()。

UPD:与标记的变量作为易失性

确认m_bIsTerminated被标记为不稳定,你应该确定。虽然看起来很奇怪,我认为你会//设置后,更多的代码“被终止”为真。究竟是什么变量说明什么?

您“竞态条件”是你的//更多的代码,各种元素可以以不同的顺序执行。您的变量没有帮助,。你的目标是让他们在一个确定的顺序执行?如果是的话,你需要一个条件变量等待的一个线程,并在另一组。如果你不希望他们同时执行,关键部分就可以了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top