3

我有一个多线程应用程序(C++),我需要增加/更改一系列值。 如果我使用一系列互锁操作,它们是否被认为是单个原子操作?像这样的例子:我可以使用互锁操作更新多个值以避免锁定临界区/互斥量吗?

InterlockedIncrement(&value1); 
InterlockedIncrement(&value2); 
InterlockedExchange(&oldValue, newValue); 

或者它会更好地执行同步?就像这样:

EnterCriticalSection(&cs); 
value1++; 
value2++; 
oldValue = newValue; 
LeaveCriticalSection(&cs); 

我觉得需要一个锁,但我不知道......所有的值是无论是在旧的国家,还是在新的,一起是非常重要的。

回答

14

InterlockedIncrement本身是一个原子操作,但系列InterLockedIncrement不原子在一起。如果您的要求是获得一系列操作的原子性,那么您可以使用临界区。

+2

要添加到此,请勿直接使用EnterCriticalSection&LeaveCriticalSection,因为如果发生异常,LeaveCriticalSection可能不会被调用。因此,使用CSingleLock类将自动为您锁定和解锁关键部分。 – Naveen 2009-06-12 05:03:34

1

您应该使用临界区来确保原子性。

4

如果必须完全执行这些值才能保持一致的状态,则需要使用临界区。例如,如果你的价值观实际上是类似

President = Barack Obama; 
    VP = Joe Biden; 

,你没有使用一个关键部分,你可能会在奥巴马置于总统和切尼副总裁是如果你有一些情况执行这些语句之间的中断或上下文切换。这种状态不一致,我想大家都会同意:)

不过,如果你正在做的事情一样

Debit $5 from account; 
    Credit $2 to account; 

和每个操作的结果,留下了一个完整的状态,联锁将被罚款。

+1

+1这个不错的例子.. – Naveen 2009-06-12 05:05:47

1

你必须定义“状态”是什么。看起来你希望所有三个变量都是原子变化的 - 在这种情况下,三个单独的原子是不够的。但是,如果可以将所有状态组合到某种对象中,则应该可以使用“交换指针”技术来更新状态。

1

你是对的,因为所有的价值观都是旧状态或新状态,您应该使用关键部分