比较和交换如何用于任何共享数据结构的无等待互斥?

Posted

技术标签:

【中文标题】比较和交换如何用于任何共享数据结构的无等待互斥?【英文标题】:How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? 【发布时间】:2013-12-31 22:19:39 【问题描述】:

对于多线程和互斥锁,我正在浏览***作为初学者。我遇到了这部分:

CAS 可用于通过创建一个链表来实现任何共享数据结构的无等待互斥,其中每个节点代表要执行的所需操作。然后在插入新节点期间使用 CAS 更改链表中的指针。只有一个进程可以在其 CAS 中成功;同时尝试添加节点的所有其他进程都必须重试。然后每个进程可以保留数据结构的本地副本,并在遍历链表时,可以在其本地副本上执行链表中的每个操作。

现在我了解了 CAS 的基本概念,我们基本上使用原子操作将值与预定值进行比较,如果匹配,我们交换它们。但我无法理解这里的“所需操作的链接列表”是什么意思? 为什么所有进程都遵循相同的操作链表?

【问题讨论】:

【参考方案1】:

链表保存对共享数据结构的操作。

例如,如果我有一个堆栈,它将通过 push 和 pop 进行操作。链表将是伪共享堆栈上的一组推送和弹出。共享该堆栈的每个线程实际上都有一个本地副本,并且要到达当前共享状态,它将遍历操作的链接列表,并将每个操作应用到堆栈的本地副本。当它到达链表的末尾时,它的本地副本保持当前状态(当然,它随时可能变得陈旧)。

在传统模型中,每次推送和弹出都会有某种锁。每个线程都会等待获取锁,然后执行 push 或 pop,然后释放锁。

在这个模型中,每个线程都有一个堆栈的本地快照,它通过应用链表中的操作来与其他线程的堆栈视图保持同步。当它想要操作堆栈时,它根本不会尝试直接操作它。相反,它只是将其推送或弹出操作添加到链表中,因此所有其他线程都可以/将看到该操作并且它们都可以保持同步。然后,当然,它会应用链表中的操作,并且当(例如)存在弹出时,它会检查哪个线程要求弹出。当且仅当它是请求此特定弹出的线程时,它才使用弹出的项目。

【讨论】:

您的意思是“伪共享堆栈”吗?

以上是关于比较和交换如何用于任何共享数据结构的无等待互斥?的主要内容,如果未能解决你的问题,请参考以下文章

linux进程间通信--共享内存

忙等待中的互斥

Unix网络编程-同步

多线程同步和互斥有几种实现方法,都是什么?

用互斥锁保护临界区

c++11 进程间原子和互斥锁