Kos*_*lma 3 c++ multithreading atomic
布尔标志由两个线程切换.以下代码是否有意义?
static bool ATOMIC_BOOL_READ( volatile bool& var )
{
return __sync_fetch_and_or(&var, 0);
}
static void ATOMIC_BOOL_WRITE(volatile bool& var, bool newval )
{
__sync_bool_compare_and_swap( &var, !newval, newval);
}
Run Code Online (Sandbox Code Playgroud)
请注意以下几点:
我正在传递一个bool引用.合理?
为了一蹴而就,我也宣称它不稳定.
更新:
我想问的基本问题是:原子性和记忆障碍之间的区别是什么?如果线程A正在变量foo上执行原子内置,则线程B不能对变量foo执行任何操作; 因此创造了一个记忆障碍?
__sync_bool_compare_and_swap是正确的,但可能比必要的要贵得多。
这取决于你需要什么。__sync_lock_test_and_set会更便宜(并且保证是原子的),但它不会报告操作是否“成功”,因为该值是预期的(无论如何它总是“成功”,并且您也确实得到了该值,它如果不是你所说的那样,就不会失败)。然而,这些信息并不总是令人感兴趣。
std::atomic<bool>如果您在 C++0x 模式下编译,则可以使用原子内置函数,它提供.load()和.store()。这些函数可能更高效(要么利用某些操作是原子的知识,要么插入障碍,要么使用特殊操作,或其他什么),并且您的代码更可移植(并且更明显)。
此外,在几乎所有架构上,您还可以期望(认为不能保证!)对 bool 的写入无论如何都是原子的。
而且……这确实取决于。例如,如果您只想在一个线程中设置一个标志,并且只想查看它是否在另一个线程中设置,并且在实现这一点之前可能需要多花几微秒也没关系,您可以只分配变量无论任何原子性。
您只需要原子来读取 - 修改 - 写入操作系列.孤立的读取和写入已经是原子的.
你的问题说两个线程"切换"相同的bool.这不是你发布的函数所做的 - 如果你组合这些函数来执行切换,它仍然不是线程安全的.
为什么不用std::atomic_int?
i=0;是线程安全的,i=i+1;不是因为如果另一个线程同时做同样的事情,i可能最终只会增加一次而不是两次.这是一个读 - 修改 - 写,一个示例问题序列是(read1,read2,modify1,write1,modify2,write2)针对线程1和2.到目前为止,所以标准.
现在你能看出为什么这也不是线程安全的吗?
bool x = ATOMIC_BOOL_READ (&b);
x = !x;
ATOMIC_BOOL_WRITE (&b, x);
Run Code Online (Sandbox Code Playgroud)
您的功能无论如何都不会增加线程安全性.你可以写一个函数
bool atomic_toggle_and_return_new_value (bool * b) { ... }
Run Code Online (Sandbox Code Playgroud)
比如,基于比较和交换或测试和设置.对于更复杂的情况,"两个线程读写同一个 bool,你需要读者和编写者在一些关键部分协同同步(或者看看无锁和无等待的算法).
| 归档时间: |
|
| 查看次数: |
4189 次 |
| 最近记录: |