首页 > 解决方案 > CMPXCHG 和临界区实现

问题描述

CMPXCHG 语句的工作方式如下:

CMPXCHG (common, old, new):
    int temp
    temp <- common
    if common = old then
           common <- new
    return temp    

如果 CMPXCHG 原子指令可用,那么实现临界区的最简单算法是什么?

标签: cconcurrencyparallel-processingcritical-sectiontest-and-set

解决方案


如果要创建一个简单的临界区(使用Windows 定义的 aCRITICAL_SECTION),可以查看以下伪代码:

EnterCS(cs):
    If CMPXCHG(cs,0,1) = 0 
        Return True
    Return False

ExitCS:
    If CMPXCHG(cs,1,0) = 1 
        Return True
    Return False

然后使用它就变成了一个简单的例子:

If EnterCS(cs)
    SomeValue <- SomeValue + 10 
    ExitCS(cs)

这个获取其实更像是一个try-to-acquire,延伸到CS的更常见的获取方案,我们把方法改成这样

EnterCS(cs):
    While CMPXCHG(cs,0,1) != 0
        SpinOneCycle()
    Return True

这种简单的锁有其各种问题,例如无法处理递归,您需要为此保持递归锁计数。我建议使用操作系统提供的东西。如果您确实需要编写自己的锁,英特尔有一些关于编写高性能和可扩展自旋锁的出版物,您可以在此处阅读其中一个用于 Xeon 处理器另一个用于 x86此处。Lockless Inc 也有一篇关于自旋锁的文章


推荐阅读