[Swift] Command Line Tool로 키오스크 만들기(2) : GDC, Dispatch Queue, Main/Global Queue 멀티스레드

Oni·2023년 9월 3일
0

TIL

목록 보기
15/47
post-thumbnail

원문 포스팅 🔗

과제 수행 중 5초마다 콘솔창에 업데이트 되는 데이터를 프린트 해야하는 선택 요구사항이 있다.
해당 요구사항을 충족하기 위해서는 먼저 우리가 만드려고 하는 프로그램에 업데이트 되는 항목이 뭐가 있는지부터 고민을 해야한다.

우리는 영화관 키오스크이기 때문에 사실 n초 마다 업데이트 해야 할 사항은 딱히 없다.
만약에 해당 프로그램을 어플로 만드려고 하는거면 좌석표라던지 팝업창으로 광고를 띄우는 등의 기능이 있을테지만,
화면이 하나뿐인 콘솔창에서 어떤 데이터를 보여줘야 하는지부터 고민이 많았다.

그래도 해당 기능을 구현하고자 하는 팀원들의 의지로 현재 시간 기준 가장 빨리 예매할 수 있는 상영작 리스트를 업데이트 해주기로 했다.
해당 기능을 구현하기 위해서 멀티스레드를 활용했다.

1. GDC(Grand Central Dispatch)

프로그램이 실행할 때 여러가지 작업을 수행하게 되는데, 해당 작업들을 나누어서 수행할 수 있게 분배하는 과정이며, 이는 동시성 프로그래밍이라고 한다.
GCD는 멀티 코어와 멀티 프로세싱 환경에서 최적화된 프로그래밍을 할 수 있도록 애플이 개발한 기술이다.

실행할 코드(Task)를 생성하고 DispatchQueue에 추가하면 GCD가 알아서 스레드*에 배분하고 관리한다.

*현재 작업중이고 실행하고 있는 화면에서 동시에 추가 작업을 수행해야 할 때, 다른 스레드에 해당 작업을 수행시키고 현재 화면에 동기/비동기로 띄울 수 있다.

2. Dispatch Queue

Dispatch Queue는 작업을 하나씩 실행시키거나 여러 작업을 동시에 병렬로 실행시킬 수 있으며, 각 Queue는 Sync, Async로 나눌 수 있다.

  • Serial Queue : 직렬
  • Concurrent Queue : 병렬
  • Sync : 동기
  • Async : 비동기

상기 4개는 조합하여 사용할 수 있는데, 우리 프로그램에서는 Concurrent Queue - Async 조합을 사용하였다.

3. Main , Global Queue

  • Main Queue : 메인 스레드에서 사용되는 Serial Queue (모든 UI 처리는 메인에서 해야함)
  • Global Queue : 처리 우선순위를 지정할 수 있는 QOS(Quality of Service) 파라미터를 제공하는 Concurrent Queue
    • QOS 우선순위
      • userInteractive
      • userInitiated
      • default
      • utility
      • background
      • unspecified
DispatchQueue.global().async {
    while self.isNearestMovies {
        if !nearestMovies.isEmpty {
            print("빠른 예매")
            nearestMovies.forEach { movie in
                if let firstTime = movie.timeTable.first {
                    print("\(movie.title) \(firstTime.time) \(firstTime.remainedSeat)/12")
                } else {
                    print("현재 상영 중인 영화가 없습니다.")
                }
            }
        } else {
            print("현재 상영 중인 영화가 없습니다.")
        }
        sleep(5)
    }
}

빠른 예매 상영작을 메인 스레드에서 작업하지 않고, 다른 스레드에서 작업해야하기 때문에 Global Queue를 사용하여 비동기 방식으로 수행하도록 코드를 작업했다.

선택 구현사항에 GCD를 사용하여 멀티스레드를 구축하라는 전제조건이 있어서 해당 코드로 작업했지만, 그 외로도 해당 업데이트를 콘솔창에 구현하는 방법은 타이머(timer)도 있다.

let timer = DispatchSource.makeTimerSource()
timer.schedule(deadline: .now(), repeating: .seconds(20), leeway: .seconds(0))
timer.setEventHandler {
    printMessage()
}
timer.resume()
  • DispatchSource.makeTimerSource() : 인스턴스 생성
  • timer.schedule(deadline: .now(), repeating: .seconds(20), leeway: .seconds(0)) : 타이머 동작
    • deadline : 현재시간을 전달해서 즉시 시작하도록 함
    • repeating : 타이머 동작 간격
    • leeway : 실행 시간의 허용범위
  • timer.setEventHandler { printMessage() } : 타이머 실행 시 호출되는 함수 printMessage()
  • timer.resume() : 메서드 호출(타이머 시작)

타이머의 경우 현재 수정된 코드에는 타이머를 중지시키는 조건이 없어서 계속 수행되는 점이 있어 보완이 필요하다.

profile
하지만 나는 끝까지 살아남을 거야!

0개의 댓글