GCD(Grand central Dispatch)
Grand Central Dispatch(GCD)는 멀티 코어 하드웨어에서 동시성 코드 실행을 포괄적으로 지원합니다.
DispatchQueue
DispatchQueue
는 작업 아이템의 실행을 관리합니다. 대기열에 제출된 각 아이템은 시스템에 의해서 관리된 스레드풀에 의해 처리됩니다.
Serial Queue, Concurrent Queue, Sync, Async
DispatchQueue에는 크게 Serial 과 Concurrent 두 종류가 있고, FIFO(First in First out) 순서로 처리합니다. Serial은 이전 작업이 끝나면 다음 작업을 순차적으로 실행하는 직렬형태의 Queue 이고, Concurrent는 병렬형태로 실행되는 Queue 입니다.
그리고 이것은 동기(sync), 비동기(async) 방식 중 어떻게 실행하느냐에 따라 다음 처럼 4가지 조합이 나올수 있습니다.
- Serial - Sync
- Serial - Async
- Concurrent - Sync
- Concurrent - Async
sync는 큐에 작업을 추가한후, 추가된 작업이 종료될떄가지 기다립니다. async는 큐에 작업을 추가하기만 할뿐 작업의 완료 여부는 보장하지 않습니다.
Sync-Serial/Concurrent
DispatchQueue.global().sync { print("1") }
print("2")
DispatchQueue.global().sync { print("3") }
print("4")
DispatchQueue(label:"SerialQueue").sync { print("5") }
print("6")
-------
1
2
3
4
5
6
Sync는 큐에 추가한 작업이 끝날때까지 기다렸다가 다음 코드를 수행하므로 동일한 순서를 보장합니다.
Async-Serial
DispatchQueue(label:"SerialQueue").async { print("1") }
print("2")
DispatchQueue(label:"SerialQueue").async { print("3") }
print("4")
DispatchQueue(label:"SerialQueue").async { print("5") }
print("6")
-------
2
1
4
3
6
5
위에서 언급한 결과값은 실행때마다 변하지만, 1,3,5
와 2,4,6
의 순서를 고정입니다. 두 그룹의 출력 순서만 달라지게 됩니다. 214653,214365…
Async-Concurrent
DispatchQueue.global().async { print("1") }
print("2")
DispatchQueue.global().async { print("3") }
print("4")
DispatchQueue.global().async { print("5") }
print("6")
-------
2
1
4
3
6
5
여기에서 2,4,6의 출력순서만 보장되고 그 이외의 출력순서는 보장되지 않습니다. 병렬 큐에 멀티 스레드 형식으로 동작합니다.
API
MainQueue 생성
DispatchQueue.main.async { }
GlobalQueue 생성
DispatchQueue.global().sync { } // DispatchQos.QoSClass = default
DispatchQueue.global(qos: .background).async { }
Custom Dispatch Queue 생성
큐를 만들때 기본은 Serial, concurrent인 경우에 별도로 명시합니다.
// Serial Queue
DispatchQueue(label: "com.myQueue").async { }
DispatchQueue(label: "com.myQueue").sync { }
// Concurrent Queue
DispatchQueue(label: "com.myQueue"), qos: .default, attributes: .concurrent, autoreleaseFrequencyL .inherit, target: nil).async { }
asyncAfter
// Second 단위는 Double
// deadline 의 타입은 DispatchTime
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { }
/*
enum DispatchTimeInterval: Equatable {
case seconds(Int)
case milliseconds(Int)
case microseconds(Int)
case nanoseconds(Int)
case never
public static func == (lhs: DispatchTimeInterval, rhs: DispatchTimeInterval) -> Bool
}
*/
// 더 자세하게 하고싶다면
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)
Reference
GCD GitHub
Dispatch Documents
DispatchQueue Documents
GCD overview
giftbot님 blog
giftbot님 blog