ABA问题
来源:互联网 发布:睡眠软件app 编辑:程序博客网 时间:2024/06/07 03:00
ABA问题分析
/* Naive lock-free stack which suffers from ABA problem.*/ class Stack { std::atomic<Obj*> top_ptr; // // Pops the top object and returns a pointer to it. // Obj* Pop() { while(1) { Obj* ret_ptr = top_ptr; if (!ret_ptr) return nullptr; // For simplicity, suppose that we can ensure that this dereference is safe // (i.e., that no other thread has popped the stack in the meantime). Obj* next_ptr = ret_ptr->next; // If the top node is still ret, then assume no one has changed the stack. // (That statement is not always true because of the ABA problem) // Atomically replace top with next. if (top_ptr.compare_exchange_weak(ret_ptr, next_ptr)) { return ret_ptr; } // The stack has changed, start over. } } // // Pushes the object specified by obj_ptr to stack. // void Push(Obj* obj_ptr) { while(1) { Obj* next_ptr = top_ptr; obj_ptr->next = next_ptr; // If the top node is still next, then assume no one has changed the stack. // (That statement is not always true because of the ABA problem) // Atomically replace top with obj. if (top_ptr.compare_exchange_weak(next_ptr, obj_ptr)) { return; } // The stack has changed, start over. } } };
举个例子:当前全局变量s ,s的数据是 top->A->B->C
{ // Thread 2 runs pop: ret = A; next = B; compare_exchange_weak(A, B) // Success, top = B return A; } // Now the stack is top → B → C { // Thread 2 runs pop again: ret = B; next = C; compare_exchange_weak(B, C) // Success, top = C return B; } // Now the stack is top → C delete B; { // Thread 2 now pushes A back onto the stack: A->next = C; compare_exchange_weak(C, A) // Success, top = A }
由例子可以看出 假色全局变量 stack s;加入当前存在两个线程对这个全局变量s进行操作,线程1 调用了pop 当执行到
Obj* next_ptr = ret_ptr->next;
的时候线程1 被挂起,此时线程2进行pop操作 结果变为 top->B->C 然而2继续pop 则s变为 top->C 此时线程2进行push A操作则 堆栈变为top->A->C. 线程2执行完, 线程1被唤醒,那么线程1进行
top_ptr.compare_exchange_weak(ret_ptr, next_ptr)
操作 发现 ret_ptr的确就是 A,替换成 nest_ptr(即B) 但是当前B已经被销毁了,所以程序是崩毁的。
有人使用过的一种解决办法就是修改地址法:目的就是为了使
top_ptr.compare_exchange_weak(next_ptr, obj_ptr)这个操作失败,那么怎么样才可以使这个操作失败呢?因为 他成功的前提是 top_ptr 与 next_ptr相等,所以只要使next_ptr发生变化就可以了,因为当非本线程对 next_ptr做过手脚的话 就应该留下一点痕迹 这样就可以解决该问题了。
通过考察各种基于CAS原子操作的无锁数据结构实现,目前公认可实现无锁安全的数据结构是数组和单向队列。其他实现都一定程度上受到复杂度和ABA问题的威胁。
0 0
- ABA问题
- ABA问题
- ABA问题
- ABA问题
- ABA问题
- ABA问题
- AtomicStampedReference解决ABA问题
- AtomicStampedReference解决ABA问题
- ABA问题模拟
- ABA问题及避免
- JAVA ABA问题
- CAS与ABA问题
- CAS和ABA问题
- CAS-什么是ABA问题
- aba
- 用AtomicStampedReference解决ABA问题
- ABA问题及其java解决方案
- Java CAS 和ABA问题
- C#控制台基础 可空类型int?,加法实例
- 学习使用百度地图的正确方法
- POJ-3009-Curling 2.0
- 解决php pdo传中文给mysql乱码的方案
- Handler和AsyncTask的区别
- ABA问题
- AVL平衡二叉树
- 【NOIP2012模拟8.20】Memory
- ViewPager+fragment显示数据的坑
- Socket编程中 listen函数第二个形参backlog的作用
- Ubuntu 16.04 安装wine-qq 7.8 并解决不能输入中文问题
- AGV自动导航控制系统
- Fragment懒加载
- 数独-java版