내일배움캠프 40일차

임클·2025년 4월 25일

내일배움캠프

목록 보기
41/44
post-thumbnail

GCD(Grand Central Dispatch)의 주요 개념과 사용 방법, 직렬 큐와 동시 큐의 차이, 글로벌 큐와 메인 큐의 차이, DispatchWorkItem 사용법

  1. GCD 개념 및 주요 요소
    • dispatch queue
      • 작업(task)을 제출(submit)하면 FIFO 방식으로 관리
      • 작업은 큐에 쌓이고, 큐의 특성에 따라 순차 또는 병렬로 실행
    • Quality of Service(QoS)
      • 사용자 경험, 성능 요구사항에 맞춰 우선순위 지정
      • .userInteractive, .userInitiated, .default, .utility, .background 등
    • barrier
      • concurrent 큐에서 barrier 블록을 사용하면 앞선 작업들이 모두 완료된 뒤 실행되고, barrier 이후 작업은 barrier가 끝날 때까지 대기
      • 리소스 읽기/쓰기 충돌 방지에 유용
  2. 직렬(Serial) 큐와 동시(Concurrent) 큐의 차이
    • 직렬 큐
      • 한번에 하나의 작업만 실행
      • 순서 보장: 먼저 제출된 작업이 먼저 실행
      • 예:
        let serialQueue = DispatchQueue(label: "com.example.serial")
        serialQueue.async { print("첫 번째 작업") }
        serialQueue.async { print("두 번째 작업") }
        // 항상 "첫 번째 작업" → "두 번째 작업" 순서로 출력
        
    • 동시 큐
      • 여러 작업을 동시에 실행 가능
      • 제출 순서는 보장하지만, 실제 시작·완료 시점은 스레드 스케줄러에 따라 달라짐
      • 예:
        let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
        concurrentQueue.async { print("작업 A") }
        concurrentQueue.async { print("작업 B") }
        // A·B 중 먼저 실행·완료되는 작업이 달라질 수 있음
        
  3. 글로벌 큐(Global Queue)와 메인 큐(Main Queue)의 차이
    • 글로벌 큐
      • 시스템이 제공하는 전역 concurrent 큐
      • QoS별로 4~5개 풀(pool)로 나뉘어 있음
      • 사용 예:
        DispatchQueue.global(qos: .utility).async {
            // 백그라운드 작업
        }
        
    • 메인 큐
      • main thread에 연결된 serial 큐
      • 모든 UI 업데이트는 반드시 이 큐에서 실행
      • 사용 예:
        DispatchQueue.main.async {
            // UI 작업
        }
        
  4. DispatchWorkItem 사용 방법
    • 정의 및 장점
      • 작업 단위를 캡슐화하여 재사용, 취소, 완료 핸들링 가능
      • barrier 옵션이나 notify를 쉽게 연결
    • 기본 사용
      let workItem = DispatchWorkItem {
          print("DispatchWorkItem 실행")
      }
      DispatchQueue.global().async(execute: workItem)
      
    • 취소
      workItem.cancel()
      // 작업 내에서 isCancelled 확인
      let workItem = DispatchWorkItem {
          for i in 0..<5 {
              guard !DispatchWorkItem.current!.isCancelled else { return }
              print(i)
              sleep(1)
          }
      }
      DispatchQueue.global().async(execute: workItem)
      // 나중에
      workItem.cancel()
      
    • 완료 후 처리 (notify)
      let group = DispatchGroup()
      group.enter()
      DispatchQueue.global().async {
          // 작업 A
          group.leave()
      }
      group.notify(queue: .main) {
          print("모든 작업 완료 후 실행")
      }
      
    • barrier 적용 (concurrent 큐에서)
      let concurrentQueue = DispatchQueue(label: "barrier.queue", attributes: .concurrent)
      concurrentQueue.async(flags: .barrier) {
          // barrier 블록: 앞선 모든 작업 끝난 뒤 실행
      }
      

정리

  • GCD는 queue 기반 작업 스케줄링 프레임워크로, QoS, barrier 같은 기능을 제공
  • serial vs concurrent 큐는 실행 동시성 수준과 순서 보장 방식에 차이
  • 글로벌 큐는 백그라운드 concurrent 큐, 메인 큐는 UI 처리 전용 serial 큐
  • DispatchWorkItem은 작업 취소, 재사용, notify, barrier 적용 등에 유용한 캡슐화 단위

0개의 댓글