프로세스 / 스레드
실행중인 프로그램. 실행을 위해 메모리에 올라간 프로그램앱은 iOS에 속한 프로그램이다메인 스레드/백그라운드 스레드로 구분동기(sync) / 비동기(saync)
직렬적인 작업 수행병렬적인 작업 수행GCD(Grand Central Dispath)
GCD는 동시성 프로그래밍을 돕는 프레임워크이다.
GCD 안에 DispatchQueue가 포함되어있다.
DispatchQueue


작업들이 DispatchQueue에 전달되면 DispatchQueue는 작업을 적절한 쓰레드에 할당해서 멀티쓰레드로 작업을 수행하게 해준다.
Main(메인 큐)
- 메인 쓰레드에서 실행
- UI 업데이트 관련 처리
- Serial Queue(직렬 큐)
Global(글로벌 큐)
- 백그라운드 작업을 처리
- Concurrent Queue(동시성 큐)
Custom(커스텀 큐)
- 개발자가 직접 생성하고 관리
- 직렬 또는 동시 큐 설정 가능
DispatchQueue.{큐종류}.{qos옵션}.{sync/async} {
// 수행할 작업 코드 작성
}
// 큐 종류: Main / Global / Custom
// qos: Quality Of Service
// sync: 동기적으로 작업 수행
// async: 비동기적으로 작업 수행
DispatchQueue.main.async {
// UI 업데이트 코드
self.label.text = "작업 완료!"
}
DispatchQueue.global().async {
// 네트워크 통신 또는 계산이 무거운 작업을 백그라운드에서 수행
let result = self.someHeavyComputation()
DispatchQueue.main.async {
// 결과를 메인 스레드에서 UI에 반영
self.updateUI(with: result)
}
}
// label에 큐의 고유 이름 설정
// attributes 에 serial/concurrent 설정
// 설정하지 않으면 기본값 serial(직렬)
let customQueue = DispatchQueue(label: "com.myapp.customqueue", attributes: .concurrent)
customQueue.async {
// 커스텀 큐에서 실행할 작업
}
Qos (Quality Of Service)
작업의 중요도를 시스템에 알리는 방법. 이를 통해 시스템의 리소스를 효율적으로 분배
User Interactive(최고 우선순위)User Initiated (높은 우선순위)Default (기본 우선순위)Utility (낮은 우선순위)Background (최저 우선순위)Unspecified (시스템 결정)import UIKit
// SerialQueue + sync + async 예제
// 커스텀 큐 생성. attributes를 생성하지 않으면 자동으로 SerialQueue
let serialQueue = DispatchQueue(label: "com.myapp.myqueue")
serialQueue.sync {
print("Task 1 started")
Thread.sleep(forTimeInterval: 2)// 2초 동안 쓰레드 휴식
print("Task 1 finished")
}
print("hello 1")
serialQueue.async {
print("Task 2 started")
Thread.sleep(forTimeInterval: 2)
print("Task 2 finished")
}
print("hello 2")
serialQueue.async {
print("Task 3 started")
Thread.sleep(forTimeInterval: 2)
print("Task 3 finished")
}
Task 1 started
Task 1 finished
hello 1
hello 2
Task 2 started
Task 2 finished
Task 3 started
Task 3 finished
attributes를 설정하지 않았기 때문에 직렬 큐로 설정되었고 순서가 보장되는 결과가 출력되었다. 하나의 쓰레드가 처리하기 때문에 작업의 대기가 생겼다.
import UIKit
// ConcurrentQueue + sync + async 예제
let concurrentQueue = DispatchQueue(label: "com.myapp.myqueue", attributes: .concurrent)
concurrentQueue.sync {
print("Task 1 started")
Thread.sleep(forTimeInterval: 5)
print("Task 1 finished")
}
concurrentQueue.async {
print("Task 2 started")
Thread.sleep(forTimeInterval: 4)
print("Task 2 finished")
}
concurrentQueue.async {
print("Task 3 started")
Thread.sleep(forTimeInterval: 3)
print("Task 3 finished")
}
Task 1 started
Task 1 finished
Task 2 started
Task 3 started
Task 3 finished
Task 2 finished
attributes를 .concurrent로 설정해서 병렬 큐로 설정되었다. 작업 순서 처리를 아래에 정리해보았다.
Task1은 sync이기 때문에 동기처리를 하게되어 순차적으로 "Task 1 started"이 출력되고 "Task 1 finished"가 출력되었다.
Task1에 쓰레드 휴식이 5초가 부여되었기에 쓰레드는 5초가 지난 후에 작업이 진행될 수 있다.
Task2와 Task3은 async이기 때문에 비동기처리된다. 그래서 Task2의 "Task 2 started"가 출력되고 Task3의 "Task 3 started"이 출력된다.
Task3의 쓰레드 휴식 시간이 Task2보다 짧기 때문에 "Task 3 finished"이 출력되고 "Task 2 finished"가 마지막으로 출력되었다.
import UIKit
// ConcurrentQueue + sync + async + qod 예제
let concurrentQueue = DispatchQueue(label: "com.myapp.myqueue", attributes: .concurrent)
concurrentQueue.sync {
print("Task 1 started")
Thread.sleep(forTimeInterval: 2)
print("Task 1 finished")
}
concurrentQueue.async(qos: .background) {
print("Task background started")
Thread.sleep(forTimeInterval: 2)
print("Task background finished")
}
concurrentQueue.async(qos: .userInteractive) {
print("Task userInteractive started")
Thread.sleep(forTimeInterval: 2)
print("Task userInteractive finished")
}
concurrentQueue.async(qos: .utility) {
print("Task utility started")
Thread.sleep(forTimeInterval: 2)
print("Task utility finished")
}
Task 1 started
Task 1 finished
Task userInteractive started
Task utility started
Task background started
Task userInteractive finished
Task utility finished
Task background finished
DispatchQueue는 병렬로 설정되었다.
작업 순서는 아래에 정리해보았다.
Task1은 sync이기 때문에 Task1이 모두 출력되고 다음 작업이 진행된다.
qos는 작업의 중요도에 따라 순서를 부여해 처리된다. 따라서 "Task userInteractive started" → "Task utility started" → "Task background started" 순으로 출력되었다.
3개의 작업의 쓰레드의 휴식시간이 동일하기 때문에 작업이 시작된 순서대로 종료됐다.