Dog foot print

[SWIFT] Dispatch Queue의 종류 본문

IOS/Swift

[SWIFT] Dispatch Queue의 종류

개 발자국 2021. 9. 26. 17:56

들어가기 앞서

Dispatch Queue는 어떤 쓰레드로 작업을 보내기 위한 대기행렬을 의미한다. 이 포스팅에서 다뤄볼 내용은 각 쓰레드 마다 어떤 역할을 하고 있고, 작업이 어떻게 이루어 지는지를 다뤄본다.

Main

Main 쓰레드로 작업을 보내기 위한 Queue이다. 이 Queue의 특징은 다음과 같다.

  1. Serial Queue 이다.
    • 작업이 끝나야 다음 작업이 실행된다.
  2. Main Thread에게 작업을 요청한다.
    • 유일한 쓰레드인 Main Thread 에게 요청
  3. UI업데이트 작업을 요청 할 수 있다.
    • 유일하게 UI업데이트를 요청 할 수 있다.
  4. sync메서드를 사용 할 수가 없다.
    • 이 queue로 작업을 보낼 때 sync 메서드를 사용하여 코드를 처리하면 에러가 발생한다.

사용 예시

DispatchQueue.main.async{
    print("hello world")
}

Global

MainThread를 제외한 다른 쓰레드로 작업을 전달할 때 사용한다. 이 큐의 특징은 다음과 같다.

  1. Concurrent Queue 이다.
    • 어떤 작업이 끝나기를 기다리지 않고, 다음 작업을 다른 쓰레드로 전달한다.
  2. QoS 를 설정 할 수 있다.
    • Quality Of Service의 준말이다.
    • 6개의 QOS 가 존재 한다.
      • UserInteractive
      • UserInitiated
      • default
      • utility
      • background
      • unspecified (실제로는 사용 하지 않는다.)
        • 상단에 작성된 순서대로 CPU 할당을 오래 받아 작업의 속도가 더 빠르다.
  3. 낮은 QOS에서 작업을 높은 QOS로 보내면 낮은 QOS의 성능이 높아진다.

QOS의 성능 체험 예시 코드

let qoses : [DispatchQoS.QoSClass] = [.background,.utility,.default,.userInitiated,.userInteractive]

for (i, qos) in qoses.enumerated() {
    DispatchQueue.global(qos: qos).async {
        for _ in 1...1000000 {}
        print(i)
    }
}
//끝나는 순서 4,3,2,1,0

이 코드는 시스템 사정에 의해서 동작하기에 순서가 보장되지는 않지만, 높은 확률로 우선순위가 낮은 QOS가 늦게 종료된다.

QOS 성능 상승 예시 코드

let queue = DispatchQueue.global(qos: .background)

queue.async(qos : .userInteractive){
    for _ in 0...1000000{
    }
    print("성능 업그레이드 큐 종료 ")
}

Custom

Main Queue와 Global queue는 직렬큐와 동시큐의 성질을 가진다. 모종의 이유로 Queue를 따로 만들어 관리해야 할 필요가 있을 때, Queue를 새로 만들수 있다.

let customSerialQueue = DispatchQueue(label: "default Queue Serial")
let customConcurrentQueue = DispatchQueue(label: "default Queue Concurrent", attributes: .concurrent)

반드시 메인 Thread에서 해야 할 일

UI 업데이트가 발생하는 일은 꼭 메인 쓰레드에서 작업해야 한다.

하면 안되는 코드

func updateTableView(){
    DispatchQueue.global().async{
        ... get new data from server 
        tableView.reloadData()
    }
}

Sync 메서드 주의 사항

  • main Thread 에서 다른 큐로 작업을 보낼 때, sync 메서드를 사용 하면 안된다.
    • 해당 작업이 종료될 때 까지 UI업데이트가 되지 않는다.
  • 현재의 Serial Queue에서 같은 큐로 보낼 때, sync 메서드를 사용 하면 안된다.
    • 데드락이 발생한다.

데드락 예시 코드

let queue = DispatchQueue(label : "serial")

queue.async {
    print("시작")
    queue.sync {
        print("Never")
    }
    print("종료")
}

//시작만 나오고 다른건 출력 안됨 

queue는 serial Queue로 현재의 작업이 종료되면 다음 작업을 실행한다. 그러나, 위의 예제에서는 다시 비동기로 보낸 코드안에 다시 같은 queue로 작업을 요청한다. Sync 로 보낸 코드는 print(“종료”) 가 출력되어야지 실행이 될 수 있는데, 동기적으로 보낸 코드가 종료가 되지 않아 더 이상 실행 부락능 한 상태가 된다.

#Swift #GCD

반응형

'IOS > Swift' 카테고리의 다른 글

[IOS] Serial & Concurrent Queue  (0) 2021.09.23
[IOS] Async & Sync  (0) 2021.09.23
[IOS] 쓰레드와 동시작업  (0) 2021.09.22
[Swift] 동기적 작업과 비동기적 작업  (0) 2021.09.20
[SWIFT] protocol  (0) 2021.07.21
Comments