原子变量是否无锁?

pyt*_*nic 39 c++ multithreading x86-64 atomic c++11

当我们谈论原子变量时,例如C++ 11 atomic<>,它是否可以免费锁定?或者锁定是不同的东西?如果我使用原子变量管理队列,它会比无锁队列慢吗?

int*_*jay 36

该标准未指定原子对象是否无锁.在不为类型T提供无锁原子操作的平台上,atomic<T>可以使用互斥锁来实现对象,该互斥锁不是无锁的.在这种情况下,在其实现中使用这些对象的任何容器也不会是无锁的.

该标准确实提供了一种检查atomic<T>变量是否无锁的方法:您可以使用var.is_lock_free()atomic_is_lock_free(&var).这些函数保证T在给定的程序执行中始终为相同类型返回相同的值.对于基本类型,例如int,还提供了宏(例如ATOMIC_INT_LOCK_FREE),它指定是否可以使用对该类型的无锁原子访问.

  • 有些平台只有原子**交换**指令.您可以将此用作互斥锁,并使用`std :: atomic_flag`(**是**无需锁定),但不能用于一般原子(因为它不能进行普通加载). (4认同)
  • @Useless:可能是你在嵌入式平台上只有一个1字节的原子.所以像`std :: atomic <char>`这样的东西是无锁的.但是,如果通过执行非原子的4字节操作来模拟32位整数.所以很可能`std :: atomic <int>`不会无锁.但是,您可以使用字节原子制作互斥锁(例如自旋锁). (3认同)
  • 出于兴趣,是否有不提供 _any_ 无锁原生原子的平台,或者你只是说 `atomic&lt;T&gt;` 可能不是所有大小的 `T` 的原生原子?我看不出一个没有真正的原生原子的平台如何首先实现互斥锁...... (2认同)

Use*_*ess 12

无锁通常适用于多线程之间共享的数据结构,其中同步机制不是互斥的; 目的是所有线程都应该继续取得某种进展,而不是睡在互斥锁上.

atomic<T>变量不使用锁(至少T在你的平台上本机为原子的地方),但它们在上面的意义上并不是无锁的.您可以在实现无锁容器时使用它们,但它们本身并不足够.

例如,atomic<queue<T>>不会突然std::queue变成无锁数据结构.但是,你可以实现一个真正无锁atomic_queue<T>的成员atomic.

请注意,即使atomic<int>是本机原子并且未在您的平台上使用锁模拟,也不会以任何有趣的方式使其无.从这个意义上说,Plain 已经int是无锁的:包装器可以让您明确控制内存排序,并可以访问硬件同步原语.atomic<>