- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图理解由 atomic_exchange[_explicit]
引起的内存排序并编写了以下代码:
static _Atomic int i = 123;
void *update(void *ignored){
if(atomic_exchange_explicit(&i, 200, memory_order_release) != 200){ //1
printf("Updated\n", stdout);
}
}
int main(int args, const char *argv[]){
pthread_t t1;
pthread_create(&t1, NULL, &update, NULL);
pthread_t t2;
pthread_create(&t2, NULL, &update, NULL);
sleep(1000);
}
问题:Updated\n
是否有可能被打印两次(由两个线程)?
我认为行为未定义。即使我们在 //1
处将 memory_order_release
替换为 memory_order_acquire
,UB 也会保留。生成的代码与 acq/rel/acq_rel 相同:https://godbolt.org/z/sFjcve .
这是因为我们有数据竞争,因为要保持同步关系,我们需要一个操作是 acquire
操作,下一个操作是 release
操作,并且释放操作从获取操作的释放序列中读取副作用写入的值5.1.2.4(p11)
:
In particular, an atomic operation A that performs a release operation on an object M synchronizes with an atomic operation B that performs an acquire operation on M and reads a value written by any side effect in the release sequence headed by A.
因此,使此代码的行为明确定义的唯一方法是将 atomic_exchange_explicit(&i, 200, memory_order_release) != 200
替换为 atomic_exchange(&i, 200) != 200
最佳答案
你错了。无论请求的内存顺序如何,交换都是原子的。内存排序解释了这种读取、写入或读取-修改-写入操作如何与其他操作交互,但该操作始终是原子的。
关于c - atomic_exchange_explicit/atomic_exchange 引入的内存顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55723397/
我试图理解由 atomic_exchange[_explicit] 引起的内存排序并编写了以下代码: static _Atomic int i = 123; void *update(void *ig
我是一名优秀的程序员,十分优秀!