访问unsigned char线程安全(原子)

ATa*_*lor 5 c++ multithreading thread-safety

我很清楚之前已经提出了类似的问题,而且我也知道,这个操作很可能根本就不是原子的,但是我仍然要求空闲的好奇心,并希望有一些方法可以让它成为原子.

情况:在a里面struct,有一个名为unsigned的char变量Busy.(虽然它可以移出那里并独立站立).

此变量Busy由两个并发线程修改,一个在调度时设置位,另一个在完成调度操作时清除它们.

现在,调度看起来像这样:

while(SEC.Busy&(1 << SEC.ReqID))
    if(++SEC.ReqID == 5) SEC.ReqID = 0;
sQuery.cData[2] = SEC.ReqID;
Run Code Online (Sandbox Code Playgroud)

而清理bitmaks看起来像这样:

SEC.Busy &= ~(1 << sQuery->cData[2]);
Run Code Online (Sandbox Code Playgroud)

cData [2]基本上携带有关通过网络使用哪个插槽的信息,并通过另一个线程中的回调返回.

现在的问题是:我怎样才能确保SEC.Busy(在这种困境中唯一的变量)不会被两个线程同时试图改变它而不使用互斥锁,关键部分或任何东西而撕裂如果可能的话?

我也尝试将SEC.Busy的内容分配给一个局部变量,改变它然后再写回变量,但不幸的是这个操作似乎也不是原子的.

我目前正在使用Borland C++ Builder 6,尽管GCC解决方案也可以.

非常感谢你.

Jan*_*dec 6

C++ 03(也不是C99)根本没有说明原子性.在大多数平台上,赋值是原子的(=每个人都看到旧值或新值),但由于它没有同步(=任何人在看到其他更新的新值之后可能看到旧值),无论如何它都是无用的.任何其他操作,如增量,设置位等都可能不是原子的.

C++ 11定义了std::atomic模板,它确保原子性和同步,因此您需要使用它.Boost为大多数C++ 03编译器提供了兼容的实现,gcc 从4.2开始就内置了支持,它被gcc 4.7中C++ 11所需的更高级支持所取代

Windows API早就有了"互锁操作".在引入gcc __sync函数之前,Unix替代需要汇编(几个库提供).