✅⠀동시성 프로그래밍, 병렬성 프로그래밍과 비동기 프로그래밍
프로세서
프로세서는 하드웨어적인 측면에서 컴퓨터 내에서 프로그램을 수행하는 하드웨어 유닛입니다. 대표적으로 중앙처리장치(Centeral Processing Unit-CPU)가 이에 속합니다. 한 컴퓨터가 여러 개의 프로세서를 갖는다면 멀티 프로세서라고 말합니다. 듀얼 프로세서라고 한다면 한 컴퓨터에 두 개의 프로세서가 운용된다고 할 수 있습니다.
코어
프로세서에서 코어는 주요 연산회로입니다. 싱글코어는 말 그대로 하나의 연산회로가 내장되어 잇는 것이고 듀얼코어는 두 개의 연산회로가 내장된 것을 뜻합니다. 또, 여러 개의 코어를 가진 프로세서를 멀티 프로세서라고 합니다.
프로그램(Program)과 프로세스(Process)
프로그램은 일반적으로 보조기억장치에 저장된 실행코드 즉, 생명이 없는 상태를 말합니다. 프로세스는 프로그램을 구동하여 프로그램 자체와 프로그램의 상태가 메모리상에서 실행되는 작업 단위를 말합니다. 동시에 여러 개의 프로세스를 운용하는 시분할 방식을 멀티태스킹이라고 합니다. 이러한 프로세스 관리는 운영체제에서 담당합니다.
스레드(Thread)
스레드는 하나의 프로세스 내에서 실행되는 작업흐름의 단위를 말합니다. 보통 한 프로세스는 하나의 스레드를 가지고 있지만, 프로세스 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있습니다. 이러한 방식을 멀티스레딩이라고 합니다. 그리고 프로그램 실행이 시작될 때부터 동작하는 스레드를 메인 스레드라 하고 그 외에 나중에 생성된 스레드를 서브 스레드 또는 세컨더리 스레드라고 합니다.
비동기(Asynchronous) 프로그래밍
프로그램의 주 실행 흐름을 멈추어서 기다리는 부분 없이 바로 다음 작업을 실행할 수 있게 하는 방식입니다. 즉, 코드의 실행 결과 처리를 별도의 공간에 맡겨둔 뒤 결과를 기다리지 않고 바로 다음 코드를 실행하는 병렬처리 방식입니다. 비동기 프로그래밍은 언어 및 프레임워크에서 지원하는 여러 방법으로 구현할 수 있습니다.
동시성(Concurrency) 프로그래밍
논리적인 용어로 동시에 실행되는 것처럼 보이는 것입니다. 싱글 코어(멀티 코어에서도 가능)에서 멀티스레드를 동작시키기 위한 방식으로 멀티 태스킹을 위해 여러 개의 스레드가 번갈아 가면서 실행되는 방식입니다. 동시성을 이용한 싱글 코어의 멀티 태스킹은 각 스레드들이 병렬적으로 실행되는 것처럼 보이지만 사실은 서로 번갈아 가면서 실행되고 있는 방식입니다.
병렬성(Parallelism) 프로그래밍
물리적으로 동시에 정확히 동시에 실행되는 것을 말합니다. 멀티 코어에서 멀티 스레드를 동작시키는 방식으로 데이터 병렬성(Data Parallelism)과 작업 병렬성(Task Parallelism)으로 구분됩니다.
- 데이터 병렬성 : 전체 데이터를 나누어 서브 데이터들로 만든 뒤, 서브 데이터들을 병렬 처리해서 작업을 빠르게 수행하는 방법입니다.
- 작업 병렬성 : 서로 다른 작업을 병렬 처리하는 것을 말합니다.
동시성(Concurrency)과 병렬성(Parallelism) 차이
동시성 프로그래밍과 병렬성 프로그래밍 모두 비동기(Asynchronous) 동작을 구현할 수 있지만, 그 동작 원리가 다릅니다.
- 동시성(Concurrency) : 통장을 만들러 온 N개의 대기열과 한 명 이상의 은행직원
- 병렬성(Parallelism) : 통장을 만들어온 N개 대기열과 N명의 은행직원
동시성은 싱글코어 및 멀티코어에서 모두 구현할 수 있지만, 병렬성은 멀티 코어에서만 구현할 수 있다.
iOS 환경 동시성 프로그래밍 지원 종류
- Grand Central Dispatch (GCD) : 멀티 코어와 멀티 프로세싱 환경에서 최적화된 프로그래밍을 할 수 있도록 애플이 개발한 기술입니다.
- 연산 대기열 (Operaion Queue) : 비동기적으로 실행되어야 하는 작업을 객체 지향적인 방법으로 사용합니다.
- Thread : 멀티스레드 프로그래밍을 위한 애플에서 제공하는 스레드 클래스입니다.
✅⠀Operation Queue란?
Operation Queue
- Operation은 태스크(작업)와 관련된 코드와 데이터를 나타내는 추상 클래스 입니다.
- Operation Queue는 연산(Operation)의 실행을 관리합니다.
- 대기열(Queue)에 추가한 동작은 직접 제거할 수 없습니다.
- 연산(Operation)은 작업이 끝날 때까지 대기열에 남아 잇습니다.
- 연산(Operation)을 대기열에서 제거하는 방법은 연산(Operation)을 취소하는 방법뿐입니다.
- 취소하는 방법은 연산 객체(Operation Object)의 cancel() 메서드를 호출하거나 Operation Queue의 cancellAllOperations() 메서드를 호출하여 대기열에 있는 모든 연산(Operation)을 취소하는 방법이 있습니다.
- 실행 중인 연산(Operation)의 경우 연산 객체(Operation Object)의 취소 상태를 확인하고 실행 중인 연산(Operation)을 중지하고 완료 상태로 변경됩니다.
연산 객체(Operation Object)
연산 객체는 애플리케이션에서 수행하는 연산을 캠슐화하는 데 사용하는 Foundation 프레임 워크의 Operation 클래스 인스턴스입니다.
✅⠀GCD란?
GCD(Grand Central Dispatch)
- Grand Central Dispatch(GCD)는 멀티코어와 멀티 프로세싱 환경에서 최적화된 프로그래밍을 할 수 있도록 애플이 개발한 기술입니다.
- 기본적으로 스레드 풀의 관리를 프로그래머가 아닌 운영체제에서 관리하기 때문에 프로그래머가 태스크(작업)를 비동기적으로 쉽게 사용할 수 있습니다.
- 프로그래머가 실행할 태스크(작업)을 생성하고 Dispatch Queue에 추가하면 GCD는 태스크(작업)에 맞는 스레드를 자동으로 생성해서 실행하고 작업이 종료되면 해당 스레드를 제거합니다.
디스패치 대기열(Dispatch Queue)
- 디스패치 대기열은 작업을 연속적 혹은 동시에 진행하기는 하지만, 언제나 먼저 들어오면 먼저 나가는 순서로 실행됩니다.
- Serial Dispatch Queue는 한 번에 하나의 작업만을 실행하며, 해당 작업이 대기열에서 제외되고 새로운 작업이 시작되기 전까지 기다립니다.
- 이와는 반대로 Concurrent Dispatch Queue는 이미 시작된 작업이 완료될 때까지 기다리지 않고 가능한 많은 작업을 진행합니다.
- 디스패치 대기열(Dispatch Queue)은 GCD 기술 일부입니다.
디스패치 소스 (Dispatch Source)
디스패치 소스(Dispatch Source)는 특정 유형의 시스템 이벤트를 비동기적으로 처리하기 위한 C 기반 메커니즘입니다. 특정 유형의 시스템 이벤트에 대해 정보를 캡슐화하고, 해당 이벤트가 발생할 때마다 특정 클로저(블록) 객체 혹은 기능을 디스패치 대기열(Dispatch Queue)에 전달합니다. 디스패치 소스(Dispatch Source)는 GCD 기술 일부입니다.
연산 대기열 (Operation Queue)
연산 대기열(Operation Queue)은 Concurrent Dispatch Queue와 동일하게 동작하며, Operation Queue 클래스에 의해 구현됩니다. 디스패치 대기열은 항상 먼저 들어오면 먼저 나가는 순서(FIFO - First in First out)로 작업을 실행하지만, 연산 대기열(Operation Queue)은 작업의 실행 순서를 결정할 때에 다른 요인들을 고려합니다. 연산 대기열(Operation Queue)은 디스패치 대기열(Dispatch Queue)과 매우 유사한 클래스입니다.
DispatchQueue
- DispatchQueue는 작업항목의 실행을 관리하는 클래스입니다.
- 대기열(Queue)에 추가된 작업항목은 시스템이 관리하는 스레드 풀에서 처리하고 작업을 완료하면 스레드를 알아서 해제합니다.
- DispatchQueue의 장점은 일반 스레드 코드보다 쉽고 효율적으로 코드를 작성할 수 있다는 점입니다.
- 주로 iOS에서는 서버에서 데이터를 내려받는다든지 이미지, 동영상 등 멀티미디어 처리와 같이 CPU 사용량이 많은 처리를 별도의 스레드에서 처리한 뒤 메인 스레드로 결과를 전달하여 화면에 표시합니다.
- 그리고 DispatchQueue를 생성 시 기본은 Serial입니다. Concurrent 유형으로 바꾸려면 별도로 명시만 해주면 됩니다.
대기열(Queue) 유형
- Serial
대기열(Queue)에 등록한 순서대로 작업을 실행합니다. 하나의 작업을 실행하고 실행이 끝날 때까지 대기열(Queue)에 있는 다른 작업을 미루고 있다가 이전 작업이 끝나면 실행합니다.
- Concurrent
실행 중인 작업이 끝나기를 기다리지 않고 대기열(Queue)에 있는 작업을 동시에 별도의 스레드를 사용하여 실행합니다. 즉, 병렬처리 방식입니다.
✅⠀GCD와 연산 대기열 (Operation Queue)
차이점
- Operation Queue에서는 동시에 실행할 수 있는 연산(Operation)의 최대 수를 지정할 수 있습니다.
- Operation Queue에서는 KVO(Key Value Observing)을 사용할 수 있는 많은 프로퍼티들이 있습니다.
- Operation Queue에서는 연산(Operation)을 일시 중지, 다시 시작 및 취소를 할 수 있습니다.
언제 사용해야 할까요?
- Operation Queue : 비동기적으로 실행되어야 하는 작업을 객체 지향적인 방법으로 사용하는 데 적합합니다. KVO(key Value Observing)를 사용해 작업 진행 상황을 감시하는 방법이 필요할 때도 적합합니다.
- GCD : 작업이 복잡하지 않고 간단하게 처리하거나 특정 유형의 시스템 이벤트를 비동기적으로 처리할 때 적합합니다. 예를 들면 타이머, 프로세스 등의 관련 이벤트입니다.
- Operation Queue와 GCD는 둘 다 동시성(Concurrency) 프로그래밍을 지원하는 API
- Operation Queue는 GCD를 상위수준으로 추상화한 API
- Operation Queue를 좀 더 쉽게 쓸 수 있는게 GCD
- 그러므로 GCD엔 제약사항이 존재함. (의존성, 관찰자, 일시 중지, 다시 시작 및 취소)