Search
moon
sun

[GCD] 동기/비동기/Serial/Concurrent 에 대해 알아보자

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
iOS
개발지식
Scrap
태그
기초
9 more properties
동시성을 위해 iOS 에서 지원하는 기술인 GCDOperation 의 간단한 개념과 특징을 알아보고
동기, 비동기, Serial, Concurrent 에 대해 알아보기로 하자!

🔥 GCD(Grand Central Dispatch)

멀티스레딩 을 쉽게 처리하기 위해 애플에서 제공하는 API
main Thread 가 다 하던 일들을 Queue에 보내주면 적절히 생성하여 분배해주는 기능
동작원리
우리가 DispatchQueue에 작업을 추가하면 → 작업에 맞는 스레드를 자동으로 생성해서 분배 → 작업이 종료되면 스레드 제거
DispatchQueue.global().asunc { //task 의 한단위 }
Swift
복사
📌
DispatchQueue : iOS 에서 동시성 프로그래밍을 돕기위해 제공하는 queue global : Dispatch Queue 의 종류 async : 비동기
클로저내의 task 는 하나의 작업단위이기 때문에 그 안의 동작들은 순차적으로 처리

🔥 Operation

GCD 위에서 동작하지만 아래의 두 기능을 추가로 가지고 있음
동시에 실행할 수 있는 동작의 최대 수 지정
동작 일시중지 및 취소

🔥 동기(Sync)

원래의 작업이 진행되고 있던 메인 스레드에서 global dispatch queue 로 task 를 보낸 후, 다음 라인 실행을 위해 해당 작업이 끝나기를 기다린다.
사용할 시 주의사항
메인에서 다른큐로 보낼때는 sync 사용 금지
→ 이유 : 메인스레드는 UI 작업을 해야하는 데 업데이트가 끝날때까지 기다리게 되면 화면동작오류 발생
현재와 같은 큐에 sync 작업을 보내기 금지
→ 이유 : 같은 큐에 동기적으로 작업을 보내면 데드락 발생
메인 스레드에서 DispatchQueue.main.sync 사용 금지
→ 이유 : 위의 문제와 같은 이유

🔥 비동기(Async)

원래 작업이 진행되고 있던 메인 스레드에서 global dispatch queue 로 task 를 보낸 후, 해당 작업이 끝나기를 기다리지 않고 이어서 할일을 한다.
끝나는 시간은?
swift 에서는 클로저를 통해 해당 시점을 알려줌
CompletionHandler or completion : 어떤 작업이 끝났음을 알리는 클로저
비동기 처리가 필요한 이유는?
시간 절약
시간이 많이 드는 작업은 내부적으로 비동기로 구현되어있음
ex) 서버와의 통신 (네트워크 관련)

🔥 Serial (직렬)

Queue에 쌓인 task 들을 다른 하나의 스레드에 몰아넣음
task의 시작과 종료에 대한 순서예측이 가능
언제 사용?
→ 순서가 중요한 작업들을 처리할 때

🔥 Concurrent(동시)

다른 여러개의 스레드에 나눠서 처리하는 큐
task의 시작과 종료에 대한 순서예측이 불가능
언제 사용?
→ 순서가 중요하지 않고 빠르게 처리할 때

🔥 Sync & Async & Serial & Concurrent

SerialQueue.sync : 메인 스레드의 작업 흐름이 queue에 넘긴 태스크가 끝날때까지 멈춰있고(sync), 넘겨진 task는 queue에 먼저 담겨있던 작업들과 같은 스레드에 보내지기 때문에 해당 작업들이 모두 끝나야 실행 (Serial Queue)
ConcurrentQueue.sync : 메인 스레드의 작업 흐름이 queue에 넘긴 태스크가 끝날때까지 멈춰있고(sync), 넘겨진 task는 queue에 먼저 담겨있던 작업들과 다른 스레드에 보내질 수 있기 때문에 해당 작업들이 모두 끝나지 않아도 실행 (Concurrent Queue)
SerialQueue.async : 메인 스레드의 작업 흐름이 태스크를 queue에 넘기자마자 반환되고 (async), 넘겨진 task는 queue에 먼저 담겨있던 작업들과 같은 스레드에 보내지기 때문에 해당 작업들이 모두 끝나야 실행 (Serial Queue)
ConcurrentQueue.async : 메인 스레드의 작업 흐름이 태스크를 queue에 넘기자마자 반환되고 (async), 넘겨진 task는 queue에 먼저 담겨있던 작업들과 다른 스레드에 보내질 수 있기 때문에 해당 작업들이 모두 끝나지 않아도 실행 (Concurrent Queue)

🔥 Dispatch Queue 의 종류

작업의 특성, 원하는 일처리에 따라 대기열(큐)의 특성에 맞게 작업을 넣어야 함

1. Main Queue

Serial 특성
오직 한개만 존재
메인 스레드에서 처리

2. Global Queue

Concurrent 특성
DispatchQueue.global(qos: .utility).async { //task }
Swift
복사
Quality of Service 에 따라 여러개의 종류로 나뉨
1.
userInteractive : 사용자와 직접 상호작용하는 작업(UI 업데이트, 애니메이션)
2.
userInitiated : 즉각적인 결과가 필요한 작업 (클릭)
3.
default : 일반적인 작업
4.
utility : progress bar 와 함께 길게 실행되는 작업 (데이터 다운로드)
5.
backqround : 유저가 직접 인지하지 않는 시간이 덜 중요한 작업 (동기화, 백업)
6.
unspecified : Qos 정보가 없음

3. Custom(Private) Queue

말그래로 custom
default 로 Serial 의 특성을 가졌지만 Concurrent 로도 설정가능
Qos 설정 가능
label 을 붙이면 됨
let customSerialQueue = DispatchQueue(label: "") let customConcurrentQueue = DispatchQueue(label: "", qos: .background, attributes: .concurrent)
Swift
복사