let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
// 동시성을 지원하는 큐
// 동기적으로 실행
concurrentQueue.sync {
print("동기 작업 1 시작")
sleep(2) // 작업이 2초간 실행
print("동기 작업 1 완료")
}
concurrentQueue.sync {
print("동기 작업 2 시작")
sleep(1) // 작업이 1초간 실행
print("동기 작업 2 완료")
}
print("모든 동기 작업 완료 후 실행")
// 실행결과
동기 작업 1 시작
동기 작업 1 완료
동기 작업 2 시작
동기 작업 2 완료
모든 동기 작업 완료 후 실행
위 코드는 DispatchQueue를 동시성을 지원하는 큐로 인스턴스를 만듬
그러나, sync로 동작하기 때문에 호출한 스레드, 즉 메인 쓰레드는 해당 작업이 끝날 때까지 기다리게 됨
즉, 2번 내용은 ‘직렬성’과 같음
동시성 큐를 이용해서 sync 작업을 하면 직렬성을 보장할 수 있음
Concurrent 동시
작업을 다른 여러 개의 스레드에서 처리함
각 셀에서 이미지를 로드해야 한다면, 순서는 중요하지 않음 → 빠른 게 장땡일 때 사용
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
// 동시성을 지원하는 큐
// 비동기적으로 실행
concurrentQueue.async {
print("비동기 작업 1 시작")
sleep(2)
print("비동기 작업 1 완료")
}
concurrentQueue.async {
print("비동기 작업 2 시작")
sleep(1)
print("비동기 작업 2 완료")
}
print("모든 비동기 작업 추가완료")
// 실행결과
모든 비동기 작업 추가 완료
비동기 작업 1 시작
비동기 작업 2 시작
비동기 작업 2 완료
비동기 작업 1 완료
동시성을 지원하는 큐를 만듬
async를 통해 작업을 여러 스레드로 보냄
호출한 스레드는 async, 즉 작업이 끝날 때까지 기다리지 않음
동시성 큐를 이용해서 async로 했으니, 메인 스레드의 print(”모든 비동기 작업 추가완료”)가 출력됨
직렬성을 지원하는 큐로 비동기적으로 실행한다면 ?
내가 헷갈렸던 부분
let serialQueue = DispatchQueue(label: "serialQueue")
// attrbutes: .concurrent 안 하면 직렬성을 지원하는 큐임
serialQueue.async {
print("비동기 작업 1 시작")
sleep(2) // 작업이 2초간 실행
print("비동기 작업 1 완료")
}
serialQueue.async {
print("비동기 작업 2 시작")
sleep(1) // 작업이 1초간 실행
print("비동기 작업 2 완료")
}
print("모든 비동기 작업 추가 완료")
위 코드 출력하면 뭐나올까 ? 어떻게 동작할까 ? 아래 정답있음 생각 ㄱㄱ
.
.
.
.
.
정답 코드 & 해설
// 실행결과
모든 비동기 작업 추가 완료
비동기 작업 1 시작
비동기 작업 1 완료
비동기 작업 2 시작
비동기 작업 2 완료
직렬성을 지원하는 큐는 하나의 스레드에만 작업을 보냄
async를 했으면 호출한 메인스레드는 다음 작업을 할 수 있음
단, 작업을 할당받은 하나의 스레드는 작업이 끝날 때까지 기다림
동기-비동기 / 직렬-동시
동기와 비동기
작업을 보낼 때, 호출한 스레드가 기다릴지 (= sync)
혹은 호출한 스레드가 기다리지 않고 다음 코드를 실행할 지 (= async)
직렬과 동시
Queue로 보내진 작업을 하나의 스레드로 보낼지 (= Serial)
혹은 여러 개의 스레드로 보낼 지 (= Concurrent)
DispatchQueue.global()
프로그램이 실행되면 만들어지는 하나의 DispatchQueue
말 그대로 global()이므로, 전역에서 공유함
동시성을 지원하는 큐임, Serial처럼 직렬적이지 못함
QoS를 통해서 우선순위 지정이 가능함
프로그램이 실행되면 스레드 풀을 통해 DispatchQueue가 할당할 스레드를 미리 만들어두고, 작업이 들어오면 놀고있는 스레드에게 작업을 할당함
DispatchQueue.global().async는 비동기적으로 동작함 즉, 호출한 스레드는 작업이 끝나길 기다리지 않고 다른 동작을 함
DispatchQueue.global().sync는 동기적으로 동작함 즉, 호출한 스레드는 작업이 끝날 때까지 기다림
참고로 메인스레드에서 DispatchQueue.global().sync를 했다면, 해당 큐가 할당해주는 스레드는 메인 스레드이다.