我遇到一些采用如下形式的C++03代码:
struct Foo {
int a;
int b;
CRITICAL_SECTION cs;
}
// DoFoo::Foo foo_;
void DoFoo::Foolish()
{
if( foo_.a == 4 )
{
PerformSomeTask();
EnterCriticalSection(&foo_.cs);
foo_.b = 7;
LeaveCriticalSection(&foo_.cs);
}
}
foo_.a
的读取需要保护吗?例如:
void DoFoo::Foolish()
{
EnterCriticalSection(&foo_.cs);
int a = foo_.a;
LeaveCriticalSection(&foo_.cs);
if( a == 4 )
{
PerformSomeTask();
EnterCriticalSection(&foo_.cs);
foo_.b = 7;
LeaveCriticalSection(&foo_.cs);
}
}
如果是这样,为什么?
请假定整数是32位对齐的。平台是ARM。
foo_.a
,那么是未定义行为。(§1.10/4和§1.10/21) C++03对并发没有任何规定。 - Mysticialstd::atomic
,不必担心它。 - GManNickGInterlockedRead
。据我所知,您可以使用InterlockedCompareExchange(v, 0, 0)
,但会稍微降低性能,或者使用编译器的假设和扩展(如_MemoryBarrier
),编写自己的InterlockedRead
(并确保该函数的合同假定提供的整数已正确对齐,并确保类型使得 Windows 平台可以对该整数进行原子读取)。 - GManNickGstd::atomic
在你的用例中的行为。 - GManNickG