Computer Science - Thread, Coroutine

김상헌·2023년 2월 15일
0

Computer Science

목록 보기
3/3

Process

이전 포스팅에서 Process 와 Thread 에서 간단히 다뤄봤습니다. 이이서, Process, Thread 에 대해서 잠깐 다시 짚고, Concurrency, Parallelism 그리고 Coroutine 까지 다뤄보겠습니다.

Process 는 독립된 메모리 영역을 할당받고, Process 내에서 실행되는 Thread 는 Process 의 Heap 영역을 공유하며, 고유한 Stack 영역을 할당받게 됩니다.

Process 는 최초 실행될때, OS 로 부터 특정 Physical Memory 영역과 Virtual Memory 영역을 할당 받는다고 했는데, 그럼 Process 가 점점 더 많은 메모리를 필요로 하는 경우, 어떻게 될까요?

동적 메모리 할당

프로세스는 메모리가 부족한 경우, 운영 체제에 메모리를 동적으로 요구할 수 있습니다. 운영 체제는 필요에 따라 프로세스에 추가 물리적 메모리를 할당합니다. 만약 운영 체제에 사용 가능한 물리적 메모리가 충분하지 않으면 페이징 또는 스왑과 같은 기술을 사용하여 추가 메모리를 할당할 수 있습니다.

Page file 또는 swap space

Windows 및 Linux 와 같은 일부 운영 체제는 프로세스가 현재 사용 가능한 것보다 더 많은 메모리를 필요로 할 때 추가 물리적 메모리를 할당하기 위해 Paging 또는 Swapping 이라는 기술을 사용합니다. 운영 체제는 페이지 파일이나 스왑 공간에 프로세스 메모리의 일부를 일시적으로 디스크에 저장하고 필요에 따라 검색할 수 있습니다. 이를 통해 물리적으로 사용할 수 있는 메모리보다 더 많은 메모리를 사용할 수 있으며, 디스크에 읽고 쓰는 오버헤드로 인해 성능이 저하됩니다.

Concurrency

concurrency(동시성)은 다수의 Task 를 평등하게 나눠서 실행하는 것.

10분짜리 Task 가 두개가 있다고 가정합니다.

Concurrency 하게 실행된다 ~ 라는 것은 Task 1, Task 2 가 마치 동시에 실행되는 것처럼 보인다. 라는 말입니다.

다시 말해 쉽게 생각하면 Single Core 컴퓨터가 있다고 생각할때, 여러 개의 프로그램이 실행되야 되는 경우, 실질적으로 CPU는 한 시점에 하나의 프로그램만 실행하고 있지만, 빠른 전환으로 여러 개를 실행하는 것처럼 실행된다라는 의미입니다.

Parallelism

Parallelism(병렬성)은 다수의 Task를 한번에 실행하는 것.

위와 동일한 Task 들이 Parallelism 하게 실행된다라는 것은 실질적으로 동시에 실행되는 것처럼 보이는 것이 아닌 병렬적으로 실행된다 라는 의미입니다.

예로서, 목수 한명이 두개의 집을 짓는 경우 1번 집, 2번 집을 돌아가면서 짓는 것은 동시성이지만, 목수 두명이 각 각의 집을 짓는 것은 Parallelism, 즉 병렬성이다 라고 볼 수 있습니다.

Coroutine ?

코루틴(coroutine)은 읽기 쉽고 유지보수 가능한 방식으로 비동기 비차단 코드를 작성하는 데 사용할 수 있는 가볍고 협력적인 실행 스레드이다. 독립적으로 동시에 실행되는 기존 스레드와 달리 코루틴은 협력적으로 실행되며, 이는 코루틴이 한 번에 하나씩 실행되고 필요에 따라 다른 코루틴에 제어를 제공한다는 것을 의미한다.

프로그래밍에서 코루틴은 종종 I/O 바운드 및 CPU 바운드 연산, 네트워크 프로그래밍, 이벤트 구동 프로그래밍과 같은 작업에 사용된다. 여러 스레드를 생성하고 관리하는 오버헤드 없이 여러 태스크를 효율적으로 실행할 수 있는 방식으로 코드를 구성하는 방법을 제공합니다.

코루틴은 Python, Lua, Kotlin과 같은 일부 프로그래밍 언어로 구현되며 특별한 키워드나 라이브러리를 사용하여 만들 수 있다. 전통적인 스레드 기반 동시성에 대한 인기 있는 대안이며 성능 향상, 리소스 사용 감소, 읽기 쉽고 유지 관리 가능한 코드 등 많은 이점을 제공한다

Coroutine 과 Thread 의 차이

코루틴과 스레드는 모두 프로그램에서 동시성을 처리하는 방법이지만 몇 가지 주요 차이점이 있습니다.

Task 의 단위 : Thread 는 Task 단위가 Thread 이지만, Coroutine 의 Task 단위는 Object 입니다. 아래에서 자세하게 다루겠습니다.

실행: 스레드는 독립적으로 동시에 실행되는 반면 코루틴은 협력적으로 실행되므로 한 번에 하나씩 실행되고 필요에 따라 다른 코루틴에 제어를 제공한다. 따라서 코루틴이 스레드보다 가볍고 리소스 집약적이지 않다.

동기화: 스레드는 공유 데이터에 대한 액세스를 조정하기 위해 잠금, 세마포어, 모니터와 같은 동기화 메커니즘을 필요로 하며, 코루틴은 간단한 함수 호출과 데이터 공유를 통해 통신하고 조정할 수 있다.

오버헤드: 스레드에는 더 많은 메모리와 CPU 시간이 필요하기 때문에 스레드를 만들고 관리하는 것이 코루틴을 만들고 관리하는 것보다 리소스 집약적일 수 있다.

디버깅: 다중 스레드의 실행 흐름과 상태를 추적하는 것이 더 어렵기 때문에 다중 스레드 코드를 디버깅하는 것은 코루틴을 디버깅하는 것보다 더 어려울 수 있다.

가독성: 코루틴은 비동기 코드를 이해하고 수정하기 쉬운 방식으로 구조화하는 방법을 제공하기 때문에 코드를 더 읽기 쉽고 유지할 수 있다.

일반적으로 코루틴은 I/O 바운드이거나 외부 소스의 결과를 기다려야 하는 작업에 적합한 반면 스레드는 병렬 처리를 활용할 수 있는 CPU 바운드 작업에 더 적합한 선택입니다. 코루틴과 스레드 중에서 선택할 수 있는 항목은 응용프로그램의 특정 요구사항과 시스템에서 사용할 수 있는 리소스에 따라 달라집니다.

그림을 보면서 다시 설명해보겠습니다.

위의 그림은 Single Core 인 CPU 에서 Thread 의 Context Switching 이 발생하는 예시입니다.

  1. Thread A 에서 Thread B 로 컨텍스트 스위칭
  2. Thread A 는 Thread B 가 완료까지 Blocking, 즉 Thread A 의 자원은 사용 불가 상태
  3. Thread B 가 완료되면, Thread A 가 다시 시작

그럼 Coroutine 은?

1. Thread A 가 Task 1 (Object) 를 수행하다가 작업 전환
2. Thread A 는 수행하던 Task 1 의 상태를 저장하고 Task 2 로 교체
3. Task 2 가 완료되면, Thread A 는 다시 Task 1 으로 교체하여 작업 수행

즉 Thread 는 작업의 전환에서 컨텍스트 스위칭이 발생하지만, Coroutine 의 경우 수행하던 Object 만 교체하면 동일 Thread 에서 다른 작업을 수행할 수 있음으로, Thread Level 의 컨텍스트 스위칭이 필요없습니다. 그래서 Coroutine 을 Lightweight Thread(경량 스레드) 라고 부릅니다.

References

https://aaronryu.github.io/2019/05/27/coroutine-and-thread/
https://jslee-tech.tistory.com/42

profile
배움을 즐기는 개발자입니다.

0개의 댓글