Search
Duplicate

[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
복사