Grand Central Dispatch (GCD),CPU多核处理,线程间异步高效地执行任务。在GCD的管理下,只需提供DispatchWorkItem作为单个任务,本质上是个swift 闭包。这些任务项item由GCD根据一定地规则排队自动执行。通过 queue.async(execute: workItem)。通过GCD可设置任务的优先级,以及执行顺序。
几个任务项也可以作为一个group, 通过DispatchGroup组织多任务执行,最后将所有处理完毕的结果作为单一整体汇总。
队列Queue管理着任务项的执行,可串行也可并发。串行队列一次执行一个任务,并发队列无需等待执行中的任务结束才开启下一个任务(即可同时执行多项任务)。两种队列都按照先进先出(FOFO)执行。
内部,有GCD线程池服务所有的队列。当某任务执行完成后线程即销毁。当所有的线程属于busy状态,新的线程需要暂时挂起。GCD预备了五种队列可直接使用。一种串行队列:主队列。四种异步队列分别权限为:hign,default,low,background。

1
2
3
4
5
// Do work synchronously
DispatchQueue.global().sync { ... }

// Do work asynchronously
DispatchQueue.global().async { ... }

自定义串行队列:

1
2
3
4
5
6
7
let queue = DispatchQueue(label: "Some serial queue")

// Do work synchronously
queue.sync { ... }

// Do work asynchronously
queue.async { ... }

有时,我们需要对某个任务项取消执行,这个时候需要用workItem
1
2
3
4
5
6
7
8
9
10
11
12
13
class Service {
private var pendingWorkItem: DispatchWorkItem?
let queue = DispatchQueue(label: "Some serial queue")

func doSomething() {
pendingWorkItem?.cancel()

let newWorkItem = DispatchWorkItem { ... }
pendingWorkItem = newWorkItem

queue.async(execute: newWorkItem)
}
}

批量任务处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let queue = DispatchQueue(label: "Serial queue")
let group = DispatchGroup()

queue.async(group: group) {
sleep(1)
print("Task 1 done")
}

queue.async(group: group) {
sleep(2)
print("Task 2 done")
}

group.wait()

print("All tasks done")

Task 1 done
Task 2 done
All tasks done

另外一种group.enter()方式不会阻塞当前任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let queue = DispatchQueue(label: "Serial queue")
let group = DispatchGroup()

group.enter()
queue.async {
sleep(1)
print("Task 1 done")
group.leave()
}

group.enter()
queue.async {
sleep(2)
print("Task 2 done")
group.leave()
}

group.notify(queue: queue) {
print("All tasks done")
}

print("Continue execution immediately")

Continue execution immediately
Task 1 done
Task 2 done
All tasks done

留意线程死锁
死锁1:

1
2
3
4
5
6
7
8
let queue = DispatchQueue(label: "my-queue")
queue.sync {
print("print this")

queue.sync {
print("deadlocked")
}
}

死锁2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// Create concurrent queue
let queue = DispatchQueue(label: "Concurrent queue", attributes: .concurrent)

for _ in 0..<999 {
// 1
queue.async {
sleep(1000)
}
}

// 2
DispatchQueue.main.sync {
queue.sync {
print("Done")
}
}

通过信号量控制线程数

1
2
3
4
5
6
7
8
9
10
11
12
let concurrentTasks = 3

let queue = DispatchQueue(label: "Concurrent queue", attributes: .concurrent)
let sema = DispatchSemaphore(value: concurrentTasks)

for _ in 0..<999 {
queue.async {
// Do work
sema.signal()
}
sema.wait()
}

评论