본문 바로가기
iOS/Combine

[iOS/Combine] 동시성 프로그래밍의 필요성과 Queue(큐)의 역할

by iosdevlime 2023. 4. 10.

CPU, 코어, 그리고 프로세스와 스레드의 개념을 살펴본 포스팅의

중요한 키워드와 개념을 한번 더 되짚고 넘어가자면 다음과 같습니다.

 

컴퓨터 뇌 역할을 담당하는 하드웨어, CPU2개의 작업 처리 방식을 가지고 있습니다.

① 다수의 코어(Core)를 활용한 병렬적(Parallelism) 작업
 ➟ 여러개의 코어를 중심으로 멀티 프로세스, 멀티 스레드를 통해 병렬적 작업을 실행
② 프로세스를 갈아 가며, 작업하는 동시적(Concurrency) 작업
 ➟ 마치 '동시에 실행되는 것 처럼' 보이도록 프로세스를 번갈아 실행하는 작업
 ➟ 프로세스를 번갈아 매우 빠르게 처리하므로, 마치 동시(찰나)에 진행되는 것 처럼 보임

 

하지만, 여기서 한가지 의문점이 발생할 수 있는데 말입니다..

 

다수의 코어와 스레드(멀티 프로레스, 멀티 스레드)가 있다면

굳이 동시에 작업을 하는 것 처럼 보이는 '동시성' 작업을 할 이유가 있을까요?

 

이번 포스팅을 통해 동시성 프로그래밍의 필요성을 살펴본 후,

Queue란 녀석의 역할에 대해 간단하게 알아보는 시간을 가져보겠습니다.

 

 

 


 

 

 

 

동시성 프로그래밍(Concurreny Programming)의 필요성

하드웨어적 한계 해소, 작업의 효율을 위한 프로그래밍 방식

 

동시성 프로그래밍과 연관된 스레드(Thread)

 

코어와 함께 연관되는 하드웨어(H/W) 측면의 스레드가 아닌, 

일련의 작업(흐름), 즉 동시에 다양한 작업을 수행하는 '소프트웨어(SW) 스레드' 입니다.

 

즉, (H/W) 스레드가 담당하는 작업(Task)을

단일한 (S/W)스레드가 아닌 다른 (S/W)스레드에서도 동시에 일을 시키기 위해 등장한 개념이

바로 '동시성 프로그래밍(Concurrency Programming)'입니다.

 

 

 

병렬적 작업의 한계, 동시성(Concurrency)의 필요성

  • 첫 번째, 다수의 코어를 활용할 수 없다는 물리적인 한계가 존재합니다.  
    • 다수의 코어(쿼드, 옥타코어) CPU가 출시되고 있으나, 수십개의 코어를 탑재하긴 어렵습니다.
    • 따라서, 수백, 수천의 프로세스 작업을 하기 위해 동시성이 반드시 필요합니다.
  • 두 번째, 논리적 측면에서 빠른 처리와 효율성을 위해 반드시 필요합니다.
    • 예를 들어보자면, 2코어 4스레드의 CPU환경에서, 6개의 작업이 존재합니다.
    • 4개의 작업은 오래걸리지만, 2개의 작업은 짧은 시간내로 마무리 되는 작업입니다.
    • 하지만, 오래걸리는 4개의 작업을 먼저 시작할 경우, 나머지 2개의 작업은 마냥 기다려야 합니다.

Figma와 계산기는 금방 작업이 끝난단 말이야🥺
Figma와 계산기는 금방 작업이 끝난단 말이야🥺

 

 

 

동시성 프로그래밍 처리방식

  • 병렬적 작업의 한계를 극복하기 위해, 작업(Task 혹은 Thread)를 나눠 처리하는 방식을 활용합니다.
    • (HW)스레드가 병렬적으로 작업을 하는 동시에, 더 많은 (SW)스레드를 활용합니다.
    • 이때 Core는 각 프로세스 작업을 번갈아 가며 작업하는 Context Switching 과정을 거칩니다.
  • 다시 말해, 동시성 프로그래밍은 궁극적으로 병렬성 + 동시성이 혼합된 작업 방식입니다.
    • 수 많은 (SW)스레드에게 Task(작업)을 할당하는 역할을 바로 Queue가 수행합니다.
    • Queue(큐)는, 먼저 들어온 작업부터 각각의 스레드에 배치, 일종의 스케쥴링을 담당합니다.

Context Switching(비교적 덜 과부화 된)을 통한 효율적인 프로세스 업무처리
Context Switching(비교적 덜 과부화 된)을 통한 효율적인 프로세스 업무처리

 


 

 

큐(Queue)란 무엇인가요?

스레드(Thread)의 생성 및 스케쥴링 관리를 담당하는 일종의 '대기열'

 

앞서 언급한 바와 같이, 큐(Queue)스레드(Thread), 즉 프로세스 업무를 수행하는 녀석에게 

작업을 할당하는, 일종의 '매니저' 역할을 담당한다고 볼 수 있습니다.

 

사전적 용어로는 '티켓 등 표 따위를 구매하기 위해 줄을 서는 것' 이라고 하며,

작업을 수행하는 과정에 앞서 대기하는 공간으로도 쉽게 이해할 수도 있습니다.

그렇다면, 이러한 큐(Queue)는 무슨 특징을 가지고 있으며,

역할별로 어떠한 종류가 있을까요?

 

 

큐(Queue)에 대하여

  • 큐는, 실행하고자 하는 프로세스(혹은 Task)를 받는 대기열이자 분배하는 역할을 담당합니다.
    • 스레드에 업무(Task)를 배치하기 위해 선입 선출(FIFO:First In First Out)로서 동작합니다.
    • 주의! 먼저 스레드에 배치된 업무(Task)가장 먼저 종료되진 않습니다.
  • 다시 말해, 큐(Queue)는 2개 이상의 스레드를 활용하는 스케쥴러 역할을 수행합니다.
    • 수행하고자 하는 작업을 보낼 땐, DispatchQueue 키워드를 활용합니다.
      (Dispatch  :  보내다, 파견하다)
// 표현1
DispatchQueue.global().async {
    // 작업
}

// 표현2
let queue = DispatchQueue.global()
queue.async {
    // 작업
}

 

 

큐(Queue)의 종류

  • 큐는 크게 3가지 종류로 구분되며, 원하는 코드를 통해 선언할 경우 특성에 따라 일을 처리합니다.
    • 메인(main), 글로벌(Global), 프라이빗(Private)으로 나뉩니다.
    • 주로 UIKit에서 활용하는 Queue는 메인큐(DispatchQueue.main)입니다.

 

(큐와 관련된 사항은 추후 포스팅에서 자세히 다루도록 하겠습니다)

 

 


동시성 프로그래밍(Concurrency Programming)
효율적이고 논리적인 데이터 처리방식을 위해 반드시 필요하며,
이러한 방식, 즉 작업(Task)을 수행하는 스레드(Thread)를 관리(스케쥴링)하는 것이
바로 큐(Queue)이다!

 

다음 포스팅에선 Queue에 대한 보다 상세한 내용과,

 

Combine을 사용하는 궁극적인 목적,

비동기 프로그래밍에 대해 알아보는 시간으로 돌아오겠습니다.

 

댓글