一般地,对于int num,num++(或++num),作为读-修改-写操作中,是不是原子.但我经常看到编译器,例如GCC,为它生成以下代码(在这里尝试):
由于第5行对应于num++一条指令,我们可以得出结论,在这种情况下num++ 是原子的吗?
如果是这样,是否意味着如此生成num++可以在并发(多线程)场景中使用而没有任何数据争用的危险(例如,我们不需要制作它,std::atomic<int>并强加相关成本,因为它是无论如何原子)?
UPDATE
请注意,这个问题不是增量是否是原子的(它不是,而且是问题的开头行).它是否可以在特定场景中,即在某些情况下是否可以利用单指令性质来避免lock前缀的开销.而且,作为公认的答案约单处理器的机器,还有部分提到这个答案,在其评论和其他人谈话解释,它可以(尽管不是C或C++).
我是低级别的新手,所以我完全忘记了你可能面临的问题,我甚至不确定我是否理解"原子"一词.现在我试图通过扩展程序集围绕内存操作进行简单的原子锁.为什么?为了好奇.我知道我在这里重新发明轮子,可能会过度简化整个过程.
这个问题? 我在这里提供的代码是否实现了使内存操作既线程安全又可重入的目标?
我只想做...
代码:
volatile int atomic_gate_memory = 0;
static inline void atomic_open(volatile int *gate)
{
asm volatile (
"wait:\n"
"cmp %[lock], %[gate]\n"
"je wait\n"
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (1)
);
}
static inline void atomic_close(volatile int *gate)
{
asm volatile (
"mov %[lock], %[gate]\n"
: [gate] "=m" (*gate)
: [lock] "r" (0)
);
}
Run Code Online (Sandbox Code Playgroud)
然后像:
void *_malloc(size_t size)
{
atomic_open(&atomic_gate_memory);
void *mem = malloc(size);
atomic_close(&atomic_gate_memory); …Run Code Online (Sandbox Code Playgroud) 实现无锁数据结构的典型方法是使用原子 CAS 操作,例如std::compare_exchange_strong或std::compare_exchange_weak。这种技术的使用示例可以在 Antony Williams 的“C++ Concurrency in Action”中看到,其中实现了无锁堆栈。堆栈被实现为带有std::atomic<node*>头指针的链表。CAS 操作在推送和弹出期间在此指针上执行。但是 C++ 标准保证只有无std::atomic_flag锁,其他原子类型,包括std::atomic<T*>,可能不是无锁的。
1)我是否正确理解,如果std::atomic<T*>不是无锁(std::atomic::is_lock_free()返回false),那么基于CAS操作的数据结构std::atomic<T*>不是无锁的?
2)如果是,那么,如果std::atomic_flag是某些编译器的唯一无锁原子类型,那么在 C++ 上实现无锁数据结构的替代方法是什么?