Swift GCD barrier
xxxixxxx

异步读写造成数组越界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 执行完之后才会去做其他线程操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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())
}
}

  • Post title:Swift GCD barrier
  • Post author:xxxixxxx
  • Create time:2020-11-02 00:00:00
  • Post link:https://xxxixxx.github.io/2020/11/02/100-Swift-GCD-barrier/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments