천원의 개발

Swift GCD(Grand Center Dispatch), DispatchQueue.main.sync 에서 DeadLock이 발생하는 이유 본문

iOS&Swift🍎/Swift

Swift GCD(Grand Center Dispatch), DispatchQueue.main.sync 에서 DeadLock이 발생하는 이유

천 원 2022. 9. 5. 23:14

GCD란? 

 • 멀티 스레드 환경에서 편리하게 개발할 수 있도록 애플에서 만들어 준 기술이다!!!

 • GCD 즉 동시성 프로그래밍을 지원하는 스위프트의 API가 Dispatch Queue

Sync, Async

 • Sync란 Main Thread 에서 task1, task2, task3 이 있다고 가정하면 task1을 Queue에 보낸 후 종료가 되어 응답이 올 때 까지, 기다리는 것이다!  따라서 task가 순차적으로 실행이 된다

 •  반대로 Async란 Main Thread 에 똑같이 task1, task2, task3, 이 있다고 가정하면 task1을 보낸 후 기다리지 않고 그냥 모든 task2, task3을 Queue에 던져 버리는 것을 말한다!

Serial, Concurrent

 • Queue에도 2가지의 종류가 있는데 첫 번째는 Serial이다 사용하는 Thread가 하나일 때를 말한다. Dispatch Queue에서는 Main이 Serial로 동작한다.

 • Concurrent는 Thread를 여러개 사용한다! 따라서 동시에 여러개의 task를 수행 할 수있다. Dispatch Queue에서는 Global이 Concurrent로 동작한다

그렇다면!! 총 4가지의 조합이 생긴다!

 • Sync -> Serial

 • Async -> Serial

 • Sync -> Concurrent

 • Async -> Concurrent

 

자 그러면 Async -> Concurrent 부터 보면 아래 그림처럼 여러개의 task를 동시에 수행할 수 있을 것이다. 왜냐? async를 통해 task를 다 던져 버리고 각각의 thread를 통해서 일을 실행하니까!

다음은 Sync -> Concurrent를 보쟈 

여러 개의 Thread를 사용할 수 있지만 어짜피 Queue안에 들어 있는 Task는 1개이므로 Serial Queue와 동작하는 데 있어서 차이가 없다!

 

다음으로 Async -> Serial 을 보기 전에 확인 해야 할 것이 Main Queue는 Serial이라 사용하는 Thread가 하나인데 그 하나가 바로 MainThread이다!!!

그림을 통해 확인 해보자

먼저 Main Thread에서 Async 임으로 Main Queue에 순차적으로 Task1, Task2, Task3를 던져 주게 된다. 그런 후 Main Queue에서 Main Thread 한테 Task1 실행 해줘! Task2실행 해줘! Task3실행 해줘! 가 되는 것이다.

 

예제 코드를 보면서 확인해보자!

DispatchQueue.main.async { // 보내 버리고 다음 작업 실행
    for i in 1...100 {
        print(i, terminator: " ")
    }
}

for i in 101...200 {
    print(i, terminator: " ")
}
// 101~200 출력후 1~100출력

Main Thraed에서 두 반복 문이 순차적으로 실행 되는 상황에서 첫 번째 반복문을 Main Queue로 보내 버린 후 두 번 째 반복문이 실행되고 Main Queue에서 다시 첫 번째 반복문을 Main Thread로 요청하게 되는 것이다.

 

마지막으로 Sync -> Serial을 확인해 보자

먼저 Main Thread에서 Task1을 Main Queue로 보내고 Sync 임으로 Task1의 수행이 끝날 때 까지 기다린다.

다음으로 Main Queue에서 Task1의 수행을 Main Thread 한테 부탁하게 되는데 Main Thread는 Task1이 오기 전 까지 동작을 수행 할 수 없는 상태이므로 DeadLock이 발생하게 된다!