저번 시간에는 GCD에 대해 간략하게 알아봤다. 이번 시간에는 GCD의 동작을 더 정확하게 이해하기 위해서 동기와 비동기의 개념을 알아보도록 하자.
비동기는 메인스레드에 있는 작업하나가 다른 스레드에 옮겨 갈때, 그 작업의 결과(끝나는 시점)을 기다리지 않고 바로 다음 작업이 실행되는 것이다. 여기서는 [task1]이 다른 스레드로 옮겨갔고 메인스레드에서는 [task2]가 [task1]의 작업을 기다리지 않고 즉시 실행된다.
즉 메인스레드는 다음과 같이 된다. 결국 [task1]이 오래 걸리든 안 걸리든 상관하지 않겠다는 의미이다. 이 의미를 코드로 살펴보도록 하자.
DispatchQueue.global().async {
print("나는 현재")
print("비동기를 배우는")
print("중이다...")
}
위 코드의 의미는 메인스레드에서는 global Queue로 보낸 작업(여기에서는 클로저 안에 있는 print 3개)을 기다리지 않고 바로 다음 작업을 수행하겠다. 라는 의미이다.
이번에는 동기를 알아보자. 위의 비동기의 사진과 같이 [task1]을 스레드2로 보냈지만, 메인스레드에는 여전히 block이란 것이 막고있어서 [task2]가 실행되지 않고 있다. 이것은 다른 스레드로 간 [task1]의 결과를 기다린다는 의미로도 해석될 수 있다.
DispatchQueue.global().sync {
print("나는 현재")
print("동기를 배우는")
print("중이다...")
}
이 코드를 해석하면 global Queue로 보낸 작업을 메인스레드에서는 그 작업이 끝날 때까지 기다린다는 의미가 된다 !
그런데 한 가지 의문이 드는 점이 있다. 저렇게 다른 스레드로 보낸 작업을 동기화로 기다릴거라면, 굳이 다른 스레드로 보내서 작업을 처리할 필요가 있는가? 라는 의문이다..!
그래서 실제로 많은 코드들을 보면 DispatchQueue를 사용할 때에는 주로 비동기인 async를 많이 사용하는 편이다. 결국 우리가 사용하고 싶은건 비동기 프로그래밍인데 이렇게 작업을 기다리면 무슨 소용이 있나 싶다.
그럼 여태까지 내용을 소스코드로 이해해보자.
func task1() {
print("Task 1 시작")
sleep(1)
print("Task 1 완료")
}
func task2() {
print("Task 2 시작")
print("Task 2 완료")
}
func task3() {
print("Task 3 시작")
sleep(4)
print("Task 3 완료")
}
// 비동기 작업
DispatchQueue.global().async {
task1()
}
DispatchQueue.global().async {
task2()
}
DispatchQueue.global().async {
task3()
}
// Task 1 시작
// Task 2 시작
// Task 3 시작
// Task 2 완료
// Task 1 완료
// Task 3 완료
// 동기 작업
DispatchQueue.global().sync {
task1()
}
DispatchQueue.global().sync {
task2()
}
DispatchQueue.global().sync {
task3()
}
// Task 1 시작
// Task 1 완료
// Task 2 시작
// Task 2 완료
// Task 3 시작
// Task 3 완료
이 포스트는 앨런님의 강의 내용에서 발췌했습니다.