[iOS] 한걸음씩 GCD(3) - DispatchQueue의종류와 Qos

Youth·2024년 2월 4일

한걸음씩GCD

목록 보기
3/3

한주의 마무리로 GCD아티클 3편으로 돌아온 킴스캐슬입니다

올해의 목표로 일주일에 블로그글 2개씩 쓰기를 목표로 잡았는데(그러면 일년동안 못해도 100편의 아티클은 작성할수있겠더라고요 ㅎㅎ...) 생각보다 쉽지않다는걸 느끼고있습니다

일요일은 쉬는날인데 이번주에 한편을 아직못썼다라는걸 깨닫고 노트북 앞에 앉아봤습니다
이번 포스팅은 저번 1,2편에 비하면 나름(?) 길지않은 포스팅이 될것같습니다

그럼 시작해보겠습니다:-)

DispatchQueue의 종류

DispatchQueue는 GCD를 사용할때 개발자가 단순히 대기행렬에 task(클로저단위의)를 보내는것만으로 동시성프로그래밍을 가능하게 해주는 대기행렬입니다

GCD에는 DispatchQueue가있고 DispatchQueue도 여러가지 종류가 있는데요
오늘은 세가지종류의 DispatchQueue에 대해 알아보겠습니다

1.DispatchQueue.main

말그대로 main DispatchQueue입니다(편의상 main queue라고 할게요)
main queue에 task를 보내면 main queue는 task를 알맞은 thread로 보내는 역할을 하게됩니다
이 역할은 모든 DispatchQueue가 가지는 공통적인 역할이죠

그런데 main queue의 경우엔 좀 특별합니다

다른 queue의 경우엔 대기행렬과 task를 보내서 실행할 thread가 다른데 app이 실행되면 main thead안에 main queue에서 보낸 task를 실행할 main runloop가 동시에 생성됩니다

run loop가있는곳에 thread가 배정된다고 보시면 편할것같습니다:)

결국은 queue가 task를 thread에 보낸다는건 똑같지만 실행할 thread와 queue가 동시에 존재하는건 main queue뿐입니다. 그리고 보통 main thread를 편의상 1번 thread라고 부르기도 합니다(헷갈리시지 않도록 주의해주세요)

저번시간에 동기/비동기, 직렬/동시에 대해서 배웠는데요 동기/비동기는 보내는 관점에대한이야기라고 했고 직렬/동시는 queue의 특성이라고 말씀드렸습니다. 그럼 main queue도 queue니까 queue의 특성또한 존재할겁니다

결론부터 말씀드리면 main queue의 경우엔 시리얼큐 즉, 직렬큐입니다
근데 이건 뭔가 당연할수도있는게 queue가 task를 보낼수있는 thread가 main thread밖에 없기때문에(한 thread에 묶여있으니까요) 당연히 queue의 task를 하나의 thread에만 보내는 직렬큐의 특성을 가지게됩니다. 추가적으로 main queue는 한개로 유일하고 UI작업은 main thread에서 작업해야합니다

2.DispatchQueue.global

개발을 하다보면 백그라운드에서 동작시키면될거같은데?, 백그라운드에서 돌아가는지 확인해봤어?등 백그라운드라는 말을 들어보신적이 있으실텐데요

global queue에 task를 보내면 global queue는 받는 task를 background thread로 보내줍니다(여기서 background라고 이야기하는 이유는 main thread가 UI라는 앱의 표면을 담당하는 작업이기에 Ui가 아닌 작업은 background라고 표현하는듯합니다)

그리고 iOS의 다양한 프레임워크는 모두 background에서 구동이된다고 합니다
예를들어서 동영상을 재생하는 프레임워크같은건 기본적으로는 background에서 동작하게됩니다
생각해보면 당연한게 동영상재생을 main thread에서 동작시킨다면 동영상이 끝나기전까지는 main thread에서 다른동작을 못하는거고 그렇다면 동영상을 보는중에 터치이벤트를 받을수가없게됩니다

그래서 우리가 사용하는 대부분의 iOS 프레임워크는 global queue가 task를 받아서 background thread로 task를 보내준다정도로 이해하고 계시면 좋을것같습니다

그리고 global queue또한 당연히 queue의 특성인 직렬/동시를 가지고있는데요 아무런 설정을 하지않는다면 기본은 동시큐의 특성을 가지게됩니다 하지만 원한다면 직렬큐의 특성을 가지게 설정을 할 수있습니다

global queue의 중요한 특징은 Quality of Service가 존재한다는겁니다. 서비스품질이라고 해석할수있는데 좀 쉽게말해서 중요도에 따라서 thread를 많이 배치해줄수있는 지표라고 생각하시면 좋을것같습니다

thread의 숫자는 무한하지 않습니다
이론상 무한한 thread를 만들수있으나 일정 숫자이상이된다면 context switching때문에 오히려 cost가 더 커져서 느려질겁니다

만약에 queue에 task가 4개가있을때 queue의 task를 두개의 thread에 보냈을때하고 네개의 thread에 보냈을때 하고 전체 task가 뭐가 빨리끝날까요?

만약에 thread가 두개라면 그림상으로는 3번 task가끝날때 모든 task가 끝날겁니다

하지만 thread가 4개라면 1번 task가 끝나는 시점에 모든 task가 끝나게됩니다
아마 무조건은 아니겠지만 높은 확률로 task들은 thread가 많이 배정될수록 빨리 끝날수있습니다

그리고 GCD는 Qos라는 지표를 보고 아 이 queue의 task들에게 더 많은 thread를 배정해서 빨리 끝내줘야겠구나?라고 생각하게됩니다

결국은 개발자가 이 작업은 급한작업이야 ASAP하게 끝내야해!라는 꼬리표를 qos로 달아주는겁니다

Qos의 종류는 강의 교재를 첨부하겠습니다 위로 올라갈수록 중요한작업이기에 많은 thread를 배정해준다고 생각하시면 될것같습니다

추가적인 개념

Question

qos가 .utility인 queue에 .userInitiated로 작업을 보내면 어떻게되는거지?

Answer

이런 상황에서는 queue의 품질이 .userInitiated로 변한다고합니다

3.private queue

Dispatchqueue의 마지막종류는 사용자 지정 큐라고도 부르고 private queue라고도 부르는 큐입니다. 지금까지 main queue나 global queue는 정해진 큐에 task를 보냈는데 private queue는 사용자가 이름을 붙여서 만들수있는 특징이있습니다

main thread에서 동작하지 않기때문에 background thread에서 동작하지만 global queue와 다른점은 기본이 동시큐가 아닌 직렬큐이며 동시큐로도 설정이 가능합니다. qos를 지정할수있다는점에서 global queue와 동일하지만 말그대로 queue의 이름을 지정할수있다는 차이점이 존재합니다. 그리고 qos를 지정하지 않는다면 os가 알아서 우선순위를 추론해서 정해줍니다

정리

지금까지 총 세가지의 dispatchqueue를 살펴봤습니다
마무리하기전에 정리를 해보겠습니다:)

우선 main queue의 경우엔
유일하고 main thread와 동작하며 UI업데이트 내용을 처리하는 큐이며 큐의 특성을 직렬이였습니다

DispatchQueue.main.async {
    print("Hello world!)
}

다음은 global queue인데요
종류가 유일하지 않고 기본설정은 동시큐지만 직렬큐로도 설정이가능하고 서비스품질이라는 중요도를 OS에게 알려줄수있는 Qos설정이가능합니다

DispatchQueue.global(qos: .background).async {
    print("Hello world!)
}

마지막으로 private queue입니다
label을 달아서 커스텀으로 만들수있고 글로벌큐와다르게 직렬이 default이고 마찬가지로 동시큐로도 설정이가능합니다. qos설정이가능하나 설정하지 않으면 OS가 알아서 추론해줍니다(global이 설정하지않으면 default로 설정되는것과 비교했을떄 약간 다른점이라고 볼 수 있겠네요)

DispatchQueue(label: "com.kimscastle").async {
    print("Hello world!)
}

오늘은 단순히 GCD의 대기행렬에는 이런종류가있고 이런특징이있습니다~를 설명하는 글이었던것같습니다
다음 포스팅에서는 꽤나중요한 GCD를 사용할때 주의해야할점에대해서 포스팅을 해볼예정입니다
본격적으로 GCD를 사용하는 내용이 되겠네요 ㅎㅎ

그럼 오늘은 이렇게 마무리해보도록하겠습니다
그럼 20000!

profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료

0개의 댓글