Concurrency 如何从Swift使用OSAtomicCompareAndSwapPtrBarrier?

Concurrency 如何从Swift使用OSAtomicCompareAndSwapPtrBarrier?,concurrency,swift,atomic,Concurrency,Swift,Atomic,我已经在官方网站上问过这个问题,但不幸的是没有得到答案。我目前正在尝试在Swift中构建一些简单的并发数据结构,但找不到从Swift代码调用OSAtomicCompareAndSwapPtrBarrier的方法。签名是 OSAtomicCompareAndSwapPtrBarrier( __oldValue: UnsafePointer<()>, __newValue: UnsafePointer<()>, __theValue: UnsafePointer&

我已经在官方网站上问过这个问题,但不幸的是没有得到答案。我目前正在尝试在Swift中构建一些简单的并发数据结构,但找不到从Swift代码调用
OSAtomicCompareAndSwapPtrBarrier
的方法。签名是

OSAtomicCompareAndSwapPtrBarrier(
  __oldValue: UnsafePointer<()>,
  __newValue: UnsafePointer<()>,
  __theValue: UnsafePointer<UnsafePointer<()>>)
我找不到创建
UnsafePointer
的方法。仅举一个简短的代码示例:

class Stack<A> {
  var __head: Node<A>

  init() {
    __head = Node()
  }

  func push(elem: A) {
    var newNode = Node<A>()
    newNode.elem = elem
    var currentHead: Node<A>
    do {
      currentHead = __head
      newNode.next = currentHead
    } while(!OSAtomicCompareAndSwapPtrBarrier(&currentHead, &newNode, &__head))
  }
}

class Node<A> {
  var elem: A?
  var next: Node<A>?
}
试一试

var pointer=UnsafePointer.alloc(1)
指针初始化(&_头)
这将显式分配指针并填充它

PS:不要忘了在处理完指针后调用指针.dealloc(1)


编辑:您可能需要创建一个与上述类似的
UnsafePointer
,而不是使用
&\uu head
,并将其传递给
initialize

这是一个如何在Swift中使用OSAtomicCompareAndSwapPtrBarrier或OSAtomicCompareAndSwapPtr的示例:

public final class AtomicReference<T : AnyObject> {
    private var _value : T
    public var value : T {
        get {
            OSMemoryBarrier()
            return _value
        }
        set {
            OSMemoryBarrier()
            _value = newValue
        }
    }

    private let pointer : UnsafeMutablePointer<UnsafeMutablePointer<Void>> = UnsafeMutablePointer.alloc(1)
    public init(_ value : T) {
        self._value = value
        pointer.memory = UnsafeMutablePointer<Void>(Unmanaged.passUnretained(value).toOpaque())
    }
    deinit {
        pointer.destroy()
    }

    public func compareAndSwap(#oldValue : T, newValue: T) -> Bool {
        let ov = Unmanaged.passUnretained(oldValue)
        let nv = Unmanaged.passUnretained(newValue)

        if OSAtomicCompareAndSwapPtrBarrier(UnsafeMutablePointer<Void>(ov.toOpaque()), UnsafeMutablePointer<Void>(nv.toOpaque()), pointer) {
            _value = newValue
            return true
        } else {
            return false
        }
    }
}
公共最终类原子参考{
私有var_值:T
公共var值:T{
得到{
OSMemoryBarrier()
返回值
}
设置{
OSMemoryBarrier()
_值=新值
}
}
私有let指针:UnsafeMutablePointer=UnsafeMutablePointer.alloc(1)
公共初始化(u值:T){
自我价值=价值
pointer.memory=UNSAFEMENTABLEPOINTER(未托管的.passUnretained(值).toOpaque())
}
脱硝{
pointer.destroy()
}
公共函数比较DSAP(#旧值:T,新值:T)->Bool{
设ov=Unmanaged.passUnretained(oldValue)
让nv=Unmanaged.passUnretained(newValue)
如果OSAtomicCompareAndSwapPtrBarrier(unsafemutable指针(ov.toOpaque()),unsafemutable指针(nv.toOpaque()),指针){
_值=新值
返回真值
}否则{
返回错误
}
}
}
这段代码是一个类似于Java中原子引用的类。它允许您在某些情况下使用原子操作来避免线程锁定。原子操作通常在高并发的情况下提供更高的性能

仅当上一个值与oldValue相同时,compareAndSwap函数才会更改该值。例如:

class LockArray {
    var value = NSArray()
    let lock = NSLock()
    func addItem(item : Int) {
        lock.lock()
        value = value.arrayByAddingObject(item)
        lock.unlock()
    }
}

class AtomicArray {
    let reference = AtomicRefence<NSArray>([])
    func addItem(item : Int) {
        while true {
            let oldValue = reference.value
            let newValue = oldValue.arrayByAddingObject(item)
            if reference.compareAndSwap(oldValue: oldValue, newValue: newValue) {
                break
            }
        }
    }
}
类锁数组{
var值=NSArray()
let lock=NSLock()
函数附加项(项:Int){
lock.lock()
value=value.arrayByAddingObject(项)
lock.unlock()
}
}
类原子数组{
let reference=atomicreference([])
函数附加项(项:Int){
虽然是真的{
设oldValue=reference.value
让newValue=oldValue.arrayByAddingObject(项)
if reference.compareAndSwap(旧值:旧值,新值:新值){
打破
}
}
}
}

这两个类都是线程安全的,并且做相同的事情。但是,第二种方法在高并发性下工作得更好。

试试
&&&&&uu head
。。您需要传递一个指向
和\uuu head
的指针,这应该可以做到……这也不起作用
&&&&uu head
给出“&&”不是前缀一元运算符”和
&(&&uu head)
给出“inout节点不是“@lvalue$T28”的子类型”如何在C中使用它?用一些C代码更新了我的问题此编译,但CAS总是失败,因此两个指针总是不同的。有什么想法吗?最好对代码的主要功能做一个简单的解释:)我添加了一个解释。这就是为什么你从Meth得到+1。这段代码假设分配给(和加载自)_值是原子的,这不一定是原子的。另外,当对compareAndSwap的两个调用交错时,可能会将\u值设置为过期值,从而破坏CAS语义。@fNode您是对的,这个实现并不完全正确,但我在这里仅作为使用OSAtomicCompareAndSwapPtr的示例。我认为这是为了这个目的。顺便问一下,您现在是否有原子引用的正确实现?由于引用计数,实现起来并不容易。
var pointer = UnsafePointer< UnsafePointer< Node<A> > >.alloc(1)
pointer.initialize(&__head)
public final class AtomicReference<T : AnyObject> {
    private var _value : T
    public var value : T {
        get {
            OSMemoryBarrier()
            return _value
        }
        set {
            OSMemoryBarrier()
            _value = newValue
        }
    }

    private let pointer : UnsafeMutablePointer<UnsafeMutablePointer<Void>> = UnsafeMutablePointer.alloc(1)
    public init(_ value : T) {
        self._value = value
        pointer.memory = UnsafeMutablePointer<Void>(Unmanaged.passUnretained(value).toOpaque())
    }
    deinit {
        pointer.destroy()
    }

    public func compareAndSwap(#oldValue : T, newValue: T) -> Bool {
        let ov = Unmanaged.passUnretained(oldValue)
        let nv = Unmanaged.passUnretained(newValue)

        if OSAtomicCompareAndSwapPtrBarrier(UnsafeMutablePointer<Void>(ov.toOpaque()), UnsafeMutablePointer<Void>(nv.toOpaque()), pointer) {
            _value = newValue
            return true
        } else {
            return false
        }
    }
}
class LockArray {
    var value = NSArray()
    let lock = NSLock()
    func addItem(item : Int) {
        lock.lock()
        value = value.arrayByAddingObject(item)
        lock.unlock()
    }
}

class AtomicArray {
    let reference = AtomicRefence<NSArray>([])
    func addItem(item : Int) {
        while true {
            let oldValue = reference.value
            let newValue = oldValue.arrayByAddingObject(item)
            if reference.compareAndSwap(oldValue: oldValue, newValue: newValue) {
                break
            }
        }
    }
}