Swift

Dispatch(1) : What is Dispatch and Dispatch Queue?

JoonSwift 2021. 1. 13. 02:59

[Framework] Dispatch?

Dispatch란 멀티코어 하드웨어 환경에서 시스템이 관리하는 Dispatch Queues에 작업을 제출하여 코드를 동시에 실행시킬 수 있는 방법입니다. 

Grand Central Dispatch(GCD)라고도 알려져 있는 Dispatch는 macOS, iOS, watchOS, tvOS의 멀티코어 하드웨어에서 동시성 코드 실행을 도와주는 체계적이고 포괄적인 개선 기능을 제공하는 언어 기능, 런타임 라이브러리, 시스템 향상을 포함합니다. 

 

BSD 서브시스템, Core Foundation, Cocoa APIs 는 모두 향상된 기능을 활용하여 시스템과 애플리케이션을 보다 빠르고 효율적으로, 그리고 향상된 응답성으로 실행할 수 있도록 확장되었습니다. 컴퓨팅 코어의 개수가 서로 다른 컴퓨터 또는 해당 코어를 위해 경쟁하는 여러개의 애플리케이션이 있는 환경에서 하나의 애플리케이션이 여러가지 코어를 효과적으로 사용하는 방법이 얼마나 어려울지 고려해 볼 수 있습니다. 그래서 System Level에서 운용되는 GCD는 돌아가고 있는 모든 애플리케이션들의 요구를 좀 더 잘 수용하여, 사용 가능한 시스템 자원에 균형잡힌 방식으로 그들을 매칭시켜주어 보다 효율적이게 스레드를 사용하여 성능을 높일 수 있습니다.

 

[Class] Dispatch Queue

앱의 메인 스레드 또는 백그라운드 Thread에서 Task들의 Serially 또는 Concurrently한 실행을 관리하는 개체입니다!

  • Dispatch Queue는 FIFO(First In First Out)의 구조를 가지고 있습니다.
  • 애플리케이션은 이 Dispatch Queue에 Block형식의 Task를 전달합니다.
  • Dispatch Queue는 Serially 또는 Concurrently하게 실행시킬 수 있습니다.
  • Dispatch Queue에 제출된 작업은 시스템에서 관리하는 스레드 pool에서 실행이 됩니다.
  • 앱의 메인 스레드를 사용하게 만든 Dispatch Queue를 제외하고는 시스템은 어떤 스레드를 사용하여 작업할지 보장하지 않습니다. 즉 시스템이 알아서 Thread에 배치를 한다는 이야기입니다.

또한 다음과 같은 특징도 가지고 있습니다. 

  • Work Item들을 Synchronously 또는 Asynchronously하게 스케줄할 수 있습니다.
  • Work Item을 Synchronously하게 스케줄 한다면, 코드는 item이 끝날 때 까지 기다리게 됩니다.
  • Work Item을 Asynchronously하게 스케줄 한다면, 코드는 item이 어디선가 실행되고 있을때에도 코드를 진행하게 됩니다.

⚠️ 메인 큐에서 Synchronously하게 실행시키려고 시도하면 DeadLock상태에 빠지게 됩니다.

 

간단한 Dispatch Queue를 만들어 보겠습니다. 

let dispatchQueue = DispatchQueue(label: "dispatchQueue")

처음에는 이 Dispatch Queue가 Serially하게 실행될지? 혹은 Concurrently하게 실행 될지? 잘 몰랐습니다. 그래서 직접 한번 코드를 작성하여 출력해보니

dispatchQueue.async {
    for i in 1...5 {
        print("\(i)")
    }
}
dispatchQueue.async {
    for i in 6...10 {
        print("\(i)")
    }
}

 

 

 

 

이런 결과를 얻을 수 있었습니다.

'어? 왜 async로 분명히 queue에 task를 할당했는데 왜 순차적으로 출력이 되는걸까..?'

라고 의문을 가지고 다시한번 들여다 보니!

 

 

 

 

그냥 이렇게 Dispatch Queue를 label만 적어서 만들 경우에 Dispatch Queue는 Serially한 Dispatch Queue가 만들어지게 됩니다. 그렇기에 그냥 연속적으로 실행되는 것입니다. 그럼 이것을 Concurrently하게 바꿔 보겠습니다. 

let dispatchQueue = DispatchQueue(label: "dispatchQueue", attributes: .concurrent)

간단하게 attributes: .concurrent 를 추가하였습니다. 이제 다시 실행시켜 보면!

 

 

 

두가지의 Task가 이렇게 뒤죽박죽 비동기적으로 실행되는 모습을 볼 수 있습니다. 

이렇게 간단하게 Dispatch Queue를 만들어 볼 수 있었습니다. 

다음 포스팅에서는 

Sync와 Async 그리고 global과 main에 대해서 좀 더 자세히 다뤄보겠습니다.

'Swift' 카테고리의 다른 글

Type Methods (static func & class func)  (0) 2022.03.23
Sequence  (0) 2022.01.28
Unowned?  (0) 2021.02.28
Dispatch(2) : Sync / Async / main / global  (0) 2021.01.13
Parse JSON with Swift  (0) 2020.12.23