Swift 相关

Swift GCD barrier

2020-11-08  本文已影响0人  xxxixxxx

异步读写造成数组越界

let count = 100000
var array = Array(0 ... count)

func getLast() -> Int {
// ⚠️⚠️ 这里加了判断看似安全,但在异步操作时 判断 array.count > 0 的同时可能就有一个异步的操作改变了数组
    if array.count > 0 {
        return array[array.count - 1]
    }
    return -1
}

func removeLast() {
    array.removeLast()
}

DispatchQueue.global().async {
    for _ in 0 ... count {
        removeLast()
    }
}

DispatchQueue.global().async {
    for _ in 0 ... count {
        print(getLast())
    }
}

使用 barrier

会保证在同一个队列中 .barrier 执行完之后才会去做其他线程操作

let count = 100000
var array = Array(0 ... count)
let arrayQueue = DispatchQueue(label: "arrayQueue", attributes: DispatchQueue.Attributes.concurrent)

func getLast() -> Int {
    arrayQueue.sync { () -> Int in
        if array.count > 0 {
            return array[array.count - 1]
        }
        return -1
    }
}

func removeLast() {
//⚠️⚠️ 这里使用 barrier 
    let workItem = DispatchWorkItem(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
        array.removeLast()
    }
    arrayQueue.async(execute: workItem)
}

DispatchQueue.global().async {
    for _ in 0 ... count {
        removeLast()
    }
}

DispatchQueue.global().async {
    for _ in 0 ... count {
        print(getLast())
    }
}

上一篇 下一篇

猜你喜欢

热点阅读