Multithreading ABA在多线程中的实际示例
我正在寻找一些ABA问题在多线程代码中引起麻烦的真实例子 ABA问题发生在执行原子比较和交换指令时的并发代码中。如果一个线程在执行比较和交换之前立即中断,则第二个线程可能会将比较和交换的目标从其初始值a更改为不同的值B。如果在第一个线程恢复之前将该值更改回a,则尽管目标值发生了更改,但比较和交换仍将成功 在许多情况下,ABA不是一个问题。以共享引用计数为例:即使同时更改了refcount,只要我们从未从已经下降到0的refcount增加,我们也不会有问题。因此,我们显然只关心目标是否与互换时的预期值相符,而不关心它在过去是否发生了变化Multithreading ABA在多线程中的实际示例,multithreading,concurrency,atomic,compare-and-swap,Multithreading,Concurrency,Atomic,Compare And Swap,我正在寻找一些ABA问题在多线程代码中引起麻烦的真实例子 ABA问题发生在执行原子比较和交换指令时的并发代码中。如果一个线程在执行比较和交换之前立即中断,则第二个线程可能会将比较和交换的目标从其初始值a更改为不同的值B。如果在第一个线程恢复之前将该值更改回a,则尽管目标值发生了更改,但比较和交换仍将成功 在许多情况下,ABA不是一个问题。以共享引用计数为例:即使同时更改了refcount,只要我们从未从已经下降到0的refcount增加,我们也不会有问题。因此,我们显然只关心目标是否与互换时的预
有一个无锁堆栈实现的例子受到ABA的影响,但我个人到目前为止还没有在生产代码中遇到这个问题。我只是好奇是否有人可以分享一些关于ABA的战争故事。假设您想使用传统的链表实现一个有序列表。假设要向列表中添加一个新值V。首先,您必须使用辅助指针AUX找到插入新元素的正确位置,并将其定位在值小于V的最后一个节点中,同时保存AUX->next以在CAS操作中进行比较。一旦你有了这个参照,你可以将NEW->next指向AUX->next,然后使用CAS切换AUX->next to NEW,如果AUX->next仍然是你保存的同一个参照。应该是这样的:
AUX = list.HEAD;
WHILE( AUX->next.value < V)
AUX = AUX->next;
OLD = AUX->next; //line 4
NEW->next = AUX->next; //line 5
IF( CAS(AUX->next, NEW, OLD)) //line 6
Success!!!
ELSE
Try again or whatever
AUX=list.HEAD;
同时(AUX->next.valuenext;
OLD=AUX->next//第4行
新建->下一步=辅助->下一步//第5行
IF(CAS(AUX->next,NEW,OLD))//第6行
成功!!!
其他的
再试一次
这是最简单的方法。问题是在第4行和第5行之间,另一个线程可能删除了“OLD”,然后插入了另一个小于V但仍大于AUX.value的元素X。如果发生这种情况,并且分配给值为X的节点的内存与以前的地址相同,则CAS将成功,但列表将不排序。如果第二个线程的操作发生在第5行和第6行之间,您将丢失值为X的节点。所有这些都是由于ABA问题。不应该CAS(AUX->next,NEW,OLD)
beCAS(AUX->next,OLD,NEW)
?