Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading ABA在多线程中的实际示例_Multithreading_Concurrency_Atomic_Compare And Swap - Fatal编程技术网

Multithreading ABA在多线程中的实际示例

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问题发生在执行原子比较和交换指令时的并发代码中。如果一个线程在执行比较和交换之前立即中断,则第二个线程可能会将比较和交换的目标从其初始值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)
be
CAS(AUX->next,OLD,NEW)