DispatchQueue로 동시성을 알아보자
이전에 DispatchQueue를 학습하면서 두개의 Serial타입의 큐로 각각 sync 한다면 어떻게 처리될지 궁금했었습니다
며칠 생각을 해보다가 정리가 되어 직접 실행시켜 보면서 알게된 것을 몇가지 적어보려고 합니다
쓰레드에 어떻게 할당되느냐에 따라 다르게 동작
DispatchQueue는 상황에 따라 적절한 쓰레드에 Task를 할당하여 줍니다
이 때 하나의 쓰레드에 몰아주어 한번에 하나만 Task를 수행할 수 있고 여러개의 쓰레드에 할당시켜 동시에 처리하게 할 수 있습니다
sync와 async, 큐 타입을 적절히 이용해 필요한 방식으로 프로그래밍 해야합니다
아래와 같이 시리얼 타입 2개, Concurrency타입 2개를 생성해 테스트를 진행해 보겠습니다
//Serial 큐
let s1 = DispatchQueue(label:"Serial1")
let s2 = DispatchQueue(label: "Serial2")
//Concurrency 큐
let c1 = DispatchQueue(label: "C1", qos:.default, attributes: .concurrent)
let c2 = DispatchQueue(label:"C2", qos:.default, attributes: .concurrent)
Sync 테스트
각 큐에 담긴 Task는 n초 만큼 대기 후 종료를 알리는 문자열을 출력합니다
print("테스트 시작 0.0")
let startTime = Date()
s1.sync {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("s1 동작종료 \(end.duration)")
}
s2.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("s2 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
s1큐에 담긴 Task는 약 5초가 소요되었고 s2에 담긴 Task는 약 7초가 소요되었습니다
그림으로 표현하자면 아래와 같습니다
1.현재 쓰레드는 s1큐에 5초짜리 작업을 넣음 + Task 수행
2.해당 작업이 끝날 때 까지 대기
3.작업이 끝나면 s2큐에 2초짜리 작업을 넣고 Task 수행
4. 해당 작업이 끝날 때 까지 대기
5. 종료 문자열을 출력
작업이 순차적으로 진행된 이유는 print문을, 큐에 Task 정의, Task 동작 까지 모두 같은 쓰레드에서 처리했기 때문입니다
Concurrency 타입 큐도 하나의 쓰레드에서 동작하므로 결과는 동일했습니다
print("테스트 시작 0.0")
let startTime = Date()
c1.sync {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("c1 동작종료 \(end.duration)")
}
c2.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("c2 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
sync, async 테스트
async는 동시에 처리할 수 있도록 다른 현재 쓰레드가 아닌 다른 쓰레드에 Task를 할당해 줍니다
따라서 두 개의 Serial 큐에 Task를 다음과 같이 실행하면 아래와 같은 결과가 나타납니다
print("테스트 시작 0.0")
let startTime = Date()
s1.async {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("1: 동작종료 \(end.duration)")
}
s2.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("2: 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
s1큐에 async로 작업을 지시했기 때문에 현재쓰레드(쓰레드1)이 아닌 다른 쓰레드에서 처리되며 완료될 때 까지 대기하지 않습니다
따라서 현재 쓰레드(쓰레드1)은 다음 작업인 s2큐에 담긴 작업을 수행하게 됩니다
Concurrent타입 큐, async작업 후 sync작업 처리
print("테스트 시작 0.0")
let startTime = Date()
c1.async {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("1: 동작종료 \(end.duration)")
}
c2.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("2: 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
Serial타입 큐와 같은 결과가 나왔습니다. async로 분기되어 다른 쓰레드에서 처리되고 async작업은 완료까지 대기하지 않기 때문에 다음 작업을 계속해서 이어갑니다
그럼 Concurrent타입 큐와 Serial타입 큐의 차이점은?
하나의 큐에서 async 작업을 먼저 수행하고 나중에 sync작업을 수행하는 코드입니다
print("테스트 시작 0.0")
let startTime = Date()
s1.async {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("1: 동작종료 \(end.duration)")
}
s1.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("2: 동작종료 \(end.duration)")
}
print("테스트 종료")
s1은 시리얼타입 큐이기 때문에 aysnc작업이더라도(다른 쓰레드에서 처리되더라도) 해당 작업이 완전히 끝날 때 까지 대기한 후 다음작업(2초작업)을 진행합니다
결과
반면 Concurrency타입은 "동시"에 처리할 수 있으니 이미 작업중인 사항이 있더라도 계속해서 진행합니다
print("테스트 시작 0.0")
let startTime = Date()
c1.async {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("1: 동작종료 \(end.duration)")
}
c1.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("2: 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
이번엔 sync뒤에 작업을 몇개 더 붙여 보겠습니다
print("테스트 시작 0.0")
let startTime = Date()
c1.async {
sleep(5)
let end = DateInterval(start: startTime,end: Date())
print("1: 동작종료 \(end.duration)")
}
c1.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("2: 동작종료 \(end.duration)")
}
c1.sync {
sleep(2)
let end = DateInterval(start: startTime,end: Date())
print("3: 동작종료 \(end.duration)")
}
c1.async {
sleep(3)
let end = DateInterval(start: startTime,end: Date())
print("4: 동작종료 \(end.duration)")
}
print("테스트 종료")
결과
'🍎iOS프로그래밍 > 오늘의 공부' 카테고리의 다른 글
iOS HIG - Human Interface Guideline 읽어보기1[iOS-1] (0) | 2022.08.07 |
---|---|
iOS - WKWebView, UIWebVie에서 에러코드 보기 (콘솔창 확인) (0) | 2022.08.02 |
iOS프로그래밍 - URL Scheme 외부 앱 호출하기 (0) | 2022.07.25 |
iOS프로그래밍 - 이미지 캐싱(NSCache) (0) | 2022.07.23 |
Mac - Source Tree 소스트리 강제종료 현상 (0) | 2022.07.16 |
댓글