본문 바로가기
iOS와 그 외/Swift

[Swift] GCD와 친해지기

by lody.park 2024. 1. 25.

멀티 쓰레딩 (Multi threading)

멀티 쓰레딩은 하나의 프로세스 내에서 이루어지던 작업을 다른 쓰레드에서 작업할 수 있도록 분산 처리할 수 있는 방법입니다.

동시에 여러 작업을 수행할 수 있어 빠르게 작업을 수행할 수 있지만, 수행 순서를 보장할 수 없습니다 

 

iOS 에서 멀티 쓰레딩을 구현하는 주요 방법은 아래와 같습니다.

 

1) GCD : 디스패치 큐를 사용하여 작업을 스케쥴링하고 병렬로 실행할 수 있습니다.

2) Operation: 오퍼레이션 큐를 사용하여 Operation 객체를 관리합니다.

 

GCD 

GCD 가 무엇이며 어떤 목적으로 사용되나요?

 

GCD (Grand Central Dispatch) 는 macOS 및 iOS 에서 다중 스레드 및 병렬 프로그래밍을 간단하게 구현할 수 있도록 해주는 기술입니다. GCD 를 이용하여 작업(Task 또는 work, job)을 비동기적으로 실행하고, 여러 작업을 동시에 처리하거나 순차적으로 처리하는 데 사용됩니다.

 

네트워크 통신,파일 I/O 등 비동기적으로 백그라운드에서 Task를 수행하거나, 메인 쓰레드에서 UI 업데이트와 관련된 작업을 처리할 때 GCD를 활용합니다.

 

+ Swift 5.5 버전 이후에 도입된 Swift Concurrency(Async/Await) 문법을 사용하면, 코드 가독성을 개선할 수 있고, GCD 큐 및 쓰레드에 대한 관리를 개발자가 아닌 시스템 내부적으로 처리하도록 할 수 있습니다. 

 

간단하게 비교하자면

Swift 동시성 관리 기술 특징
GCD - Swift와 Objective-C 에서 GCD를 사용할 때 C 언어 기반의 GCD API를 간접적으로 호출할 수 있도록 설계되었습니다.
- Swift 에서 사용하는 GCD는 쓰레드 관리와 쓰레드 풀을 추상화하여 제공합니다.
- GCD는 low-level API로 더 많은 제어를 제공하며, 복잡한 쓰레드 관리 및 작업 스케줄링이 필요한 경우에 유용합니다.
- 특히 기존 Objective-C 코드와의 호환성을 고려해야하는 경우 GCD를 사용하는 것이 좋습니다.
Concurrency - Concurrency는 Swift 언어 자체에 내장되어 있으며, 비동기 코드를 더 간단하게 작성할 수 있도록 합니다.
- Concurrency는 코드 가독성을 향상시키며, 에러 핸들링을 간편하게 처리할 수 있게 해줍니다.
- 비교적 더 high-level의 추상화를 제공하며, 대부분의 비동기 작업에 적합합니다.

 

+ 조금만 투머치 토킹을 해보겠습니다.

 

우리는 Swift 언어의 목적을 알아야합니다. Swift 언어만 봤을때, 시스템을 제어할 수 있는 모든 기능을 제공해주지는 않습니다.

Swift는 주로 어플리케이션 레벨의 개발에 사용하기 위해 만들어진 High-level의 언어입니다. High-level 언어는 프로그래머가 구현해야할 많은 기능들을 추상화하여 제공함으로써 부담을 덜어줍니다. 대신 시스템 코어적인 부분에 대한 개입이 어렵죠. 그래서 Swift는 low-level 코드를 작성할 수 있는 C 언어 기반의 라이브러리 및 코드를 호출하고 통합할 수 있습니다. 필요하면 가져다쓰라는 겁니다..ㅎㅎ

 

GCD 의 주요 구성 요소는 어떻게 되나요.

큐는 Task 를 처리하는 방식에 따라 크게 두 가지 유형으로 구분짓습니다.

- Task를 병렬로 처리 (병렬 큐, Concurrent Queue)

- Task를 순차적으로 처리 (직렬 큐, Serial Queue)

 

Main Queue는 Main Thread에서 실행되며, Thread-Safe 를 보장하기 위해 Serial Queue 로 구현됩니다.

 

 

 

동기(Sync)와 비동기(Async) Task 에 대한 이해

작성중...

 

Concurrent Queue에 있는 Task는 순차성을 보장하는 것일까?

순차성을 보장하지 않습니다.

 

GCD 의 병렬 큐(Concurrent Queue)에서는 여러 Task가 동시에 실행되지만, 각 Task의 상대적인 진행 속도와 점유율에 따라 완료 시점이 다를 수 있습니다.

 

Concurrent Queue 에서 Task 들은 서로 독립적인 쓰레드에서 실행되며, 운영체제 스케쥴러에 의해 관리됩니다. 

스케줄러는 쓰레드에 Task를 할당합니다.

 

쓰레드간 Task 전환은 수행될까?

수행되지 않습니다.

 

Worker 쓰레드는 일반적으로 한 번에 하나의 Task를 처리합니다.
쓰레드간 Task를 전환하려면 Context Switching 과정을 통해 오버헤드가 발생할 수 있습니다. GCD는 쓰레드 간의 작업 전환을 최소화하고 성능을 향상시키기 위해 Task을 시작한 쓰레드에서 완료합니다.

 

운영체제 스케쥴러는 쓰레드 간의 실행을 조정하고 쓰레드 전환을 처리합니다. 쓰레드 내에서 실행 중인 작업을 전환하는 것은 쓰레드의 실행흐름을 변경하고 예측 불가능한 결과를 초래할 수 있기 때문에 피해야 합니다.

 

Task를 중단할 수 있을까?

GCD에서 직접적으로 이미 실행중인 작업을 취소하는 것은 어렵습니다.

( *GCD 기반으로 만들어진 OperationQueue 는 작업을 취소하거나, 일시중지하거나, 일시중지된 작업을 다시 시작할 수 있는 등 GCD에서 구현하지 못하는 복잡한 기능을 구현할 수 있습니다. )

 

단, 작업 대기열에 있는 작업을 취소하는 것은 가능합니다.

 

1) DispatchWorkItem 을 사용하는 방법과 2) DispatchQueue 를 사용하는 방법이 있습니다.

 

1) DispatchWorkItem을 사용한 방법

let workItem = DispatchWorkItem {
    // 실행할 코드 작성
}

// GCD 큐에 작업 제출
DispatchQueue.global().async(execute: workItem)

// 작업 취소
workItem.cancel()

 

2) DispatchQueue를 사용한 방법

let customQueue = DispatchQueue(label: "com.jeonghi.customQueue")

// 작업을 큐에 제출
let task = customQueue.async {
    // 실행할 코드 작성
}

// 작업 취소
customQueue.async {
    task.cancel()
}

 

현재 실행중인 흐름이 Main 쓰레드에서 실행중인지 알 수 있는 방법

print(Thread.isMainThread)

 

+ Combine의 cancellable은 Task를 더이상 수행하지 않는 것일까?

 

Combine의 cancellable 을 사용하여 Task을 취소할 때 실제 Task가 중단되는 것은 아닙니다. !

cancellable은 구독중인 데이터 스트림을 더 이상 수신하지 않도록 구독 취소하는 것입니다.

 

즉, Combine의 Publisher에서 데이터를 받는 것이 중단되는 것이지, 실제 Task가 중단되는 것은 아닙니다.

참고: 
https://developer.apple.com/documentation/DISPATCH

 

Dispatch | Apple Developer Documentation

Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system.

developer.apple.com

\https://developer.apple.com/documentation/dispatch/dispatchqueue

 

DispatchQueue | Apple Developer Documentation

An object that manages the execution of tasks serially or concurrently on your app's main thread or on a background thread.

developer.apple.com

https://velog.io/@kuruma-42/Grand-Central-Dispatch-GCD

 

Grand Central Dispatch (GCD)

최근 회사에서 프로젝트로 공부할 시간이 전혀 없어서 주말을 이용해 개념을 정립하는 식의 공부를 하기로 했다. 절대적인 시간을 늘리기로다짐 했기 때문에 앞으로는 퇴근하고도 블로그 작성

velog.io