我已经在官方Apple developer forums中提出了这个问题,但遗憾的是没有得到答案。我目前正在尝试在Swift中构建一些简单的并发数据结构,但是找不到从Swift代码调用OSAtomicCompareAndSwapPtrBarrier
的方法。签名是
OSAtomicCompareAndSwapPtrBarrier(
__oldValue: UnsafePointer<()>,
__newValue: UnsafePointer<()>,
__theValue: UnsafePointer<UnsafePointer<()>>)
在C中将是
OSAtomicCompareAndSwapPtrBarrier(
void *__oldValue,
void *__newValue,
void * volatile *__theValue)
我找不到创建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(¤tHead, &newNode, &__head))
}
}
class Node<A> {
var elem: A?
var next: Node<A>?
}
使用&__head
显然不起作用,因为它只会创建UnsafePointer<()>
。那么如何在这里创建UnsafePointer<UnsafePointer<()>>
?
修改:
在C中我可以按如下方式使用它(我通常不使用C,所以这段代码可能非常错误):
#include <stdio.h>
#include <stdlib.h>
#include <libkern/OSAtomic.h>
typedef struct {
int bar;
} foo;
int main(int argc, const char * argv[]) {
// insert code here...
foo * volatile f = malloc(sizeof(foo));
foo *n = malloc(sizeof(foo));
f->bar = 1;
foo *old = f;
n->bar = 3;
OSAtomicCompareAndSwapPtrBarrier(old, n, &f);
free(old);
printf("%d\n", f->bar);
free(f);
return 0;
}
答案 0 :(得分:1)
这是一个如何在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
}
}
}
此代码是一个类似于Java中的AtomicReference的类。它使您可以在某些情况下使用原子操作来避免线程锁定。在高并发性的情况下,原子操作通常可以提供更高的性能。
仅当前一个值与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
}
}
}
}
这两个类都是线程安全的,并且做同样的事情。但是,第二个将更好地与高并发性。
答案 1 :(得分:0)
尝试
var pointer = UnsafePointer< UnsafePointer< Node<A> > >.alloc(1)
pointer.initialize(&__head)
这显式分配指针并填充它。
PS:完成后忘了打电话给pointer.dealloc(1)
......
编辑:您可能必须明确创建与上述内容类似的UnsafePointer< Node<A> >
,而不是使用&__head
并将其传递给initialize
而不是......