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
7let queue = DispatchQueue(label: "Some serial queue")
// Do work synchronously
queue.sync { ... }
// Do work asynchronously
queue.async { ... }
有时,我们需要对某个任务项取消执行,这个时候需要用workItem1
2
3
4
5
6
7
8
9
10
11
12
13class 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
16let 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
22let 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
8let 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
13dispatch_queue_t workConcurrentQueue = dispatch_queue_create("com.process.mergepicture", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t serialQueue = dispatch_queue_create("com.process.pictures",DISPATCH_QUEUE_SERIAL);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(serialQueue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(workConcurrentQueue, ^{
NSLog(@"thread-info:%@开始执行任务%d",[NSThread currentThread],(int)i);
sleep(1);
NSLog(@"thread-info:%@结束执行任务%d",[NSThread currentThread],(int)i);
dispatch_semaphore_signal(semaphore);});
});
}