우노
[OS] 프로세스, 쓰레드, 멀티 프로세스, 멀티 쓰레드란? 본문
프로그램(Program)이란?
- 개념
- 파일이 저장 장치에만 저장되어 있고, 메모리에는 올라가 있지 않은 정적인 상태를 의미합니다.
- 즉, 아직 실행되지 않은 파일(코드 덩어리)을 의미합니다.
- 특징
- 모든 프로그램은, 운영체제가 해당 프로그램을 위한 메모리 공간을 할당한 뒤, 자원을 할당해줘야 실행할 수 있습니다.
프로세스(Process)란?
개념
- 운영체제로부터 자원을 할당 받은 작업의 단위를 의미합니다.
- 즉, 프로그램이 실행된 상태를 의미합니다.
특징
- 프로그램을 실행하는 순간, 해당 파일은 운영체제가 할당해준 메모리에 올라가게 되며, 운영체제로부터 시스템 자원을 할당받게 됩니다.
- 이때, 운영체제는 각 프로세스의 독립된 메모리 영역을 Code, Data, Stack, Heap의 형식으로 할당해줍니다.
- Code : 코드 자체를 구성하는 메모리 영역
- Data : 전역 변수, 정적 변수, 배열 등
- Stack : 지역 변수, 매개 변수, 리턴 값
- Heap : 동적 할당 시 사용 (new(), malloc() 등)
- https://wooono.tistory.com/339
- 또한, 기본적으로 프로세스는 최소 1개의 쓰레드(메인 쓰레드)를 가지고 있습니다.
- 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없습니다.
- 한 프로세스가 다른 프로세스의 자원에 접근하려면, 아래 방식들을 사용해야합니다.
- IPC(Inter-Process Communication)
- LPC(Local inter-Process Communication)
- 별도로 공유 메모리를 만들어서 정보를 주고받도록 설정
예제
- 일반적으로 하나의 프로그램은 여러 개의 프로세스로 구성됩니다.
- 예를 들어, 크레이지 아케이드라는 게임은 여러가지 프로세스들이 동시에 진행됩니다.
- 물풍선을 맞고 물 속에 갇히는 프로세스
- 남은 게임 시간을 나타내는 프로세스
- 다른 캐릭터들이 움직이는 프로세스 등
- 또한, 물풍선을 맞는 프로세스도, 여러가지 프로세스들로 이루어져있습니다.
- 물풍선을 맞아서 물안에 갇히는 동작을 구현하는 프로세스
- 물소리가 나는 프로세스
- 갇힌 시간으로부터 일정 시간을 계산하는 프로세스 등
- 이때, CPU 는 각각의 프로세스를 동시 처리하지 않고,
- 1번 프로세스를 어느 정도 처리하고 저장한 뒤,
- 2번 프로세스를 어느 정도 처리하고 저장하는 방식으로 진행합니다.
- 이렇게 여러 프로세스를 왔다 갔다하는 과정을 콘텍스트 스위칭(Context Switching)이라고 합니다.
- 이렇게 프로세스 간 이동이 많아지게 되면, CPU의 부담이 늘어나게 됩니다.
- 따라서, 이를 해결하기 위해 멀티 쓰레드가 사용됩니다.
컨텍스트 스위칭(Context Switching)이란?
- 어떤 CPU 가 하나의 Task(Process 또는 Thread)를 실행하고 있는 상태에서,
- 인터럽트로 인해 CPU 가 다른 Task 를 실행해야할 때,
- 현재 실행하고 있는 Task 의 상태 또는 레지스터 값을 저장하고,
- 다음에 실행해야하는 Task 의 상태 또는 레지스터 값을 불러오는 작업을 의미합니다.
쓰레드(Thread)란?
개념
- 프로세스 내에서 프로세스가 할당 받은 자원을 이용하는 실행 흐름의 단위를 의미합니다.
- 한 프로세스 내에는 여러개의 쓰레드가 동시에 실행될 수 있습니다.
특징
- 쓰레드는, 프로세스가 할당 받은 메모리 영역 내에서, 쓰레드끼리 Code/Data/Heap 영역을 공유하고, Stack 영역은 별도로 관리합니다.
- 기본적으로 하나의 프로세스가 생성되면 하나의 쓰레드가 같이 생성되며, 이를 메인 쓰레드라고 부릅니다.
- 쓰레드를 추가로 생성하지 않는 한, 모든 프로그램 코드는 메인 쓰레드에서 실행됩니다.
- 물론, 하나의 프로세스는 여러 개의 쓰레드를 가질 수 있으며, 이를 멀티 쓰레드라고 합니다.
예제
- 프로그램 및 프로세스가 하나의 코드 덩어리라면,
- 쓰레드는 코드 내에 선언된 함수라고 이해하시면 됩니다.
프로세스와 쓰레드의 차이
- 일부 프로세스의 종료는 다른 프로세스에 영향을 미치지 않습니다.
- 각각의 프로세스는 독립적입니다.
- 하지만, 일부 쓰레드의 종료는 해당 프로세스에 영향을 미칩니다.
- 스레드는 한 프로세스 내에서 Code/Data/Heap 메모리 영역의 내용을 공유하기 때문에
- 어떤 쓰레드 하나라도 오류가 발생한다면, 같은 프로세스 내의 다른 쓰레드까지 모두 강제로 종료됩니다.
- 코드(프로세스) 내에서의 함수(쓰레드)에 빗대어 생각해보면 이해하기 쉽습니다.
- 코드 내의 어떤 함수 하나에서 오류가 발생할 경우,
- 해당 오류가 어떤 함수에서 발생했는지와 상관 없이, 해당 프로세스는 종료됩니다.
- 추가
- CPU 의 최소 작업 단위는 쓰레드입니다.
- 운영체제의 최소 작업 단위는 프로세스입니다.
멀티 프로세스(Multi Process)란?
- 개념
- 하나의 프로그램을 여러 개의 프로세스로 구성하여,
- 각 프로세스가 하나의 작업을 처리하는 것을 의미합니다.
- 장점
- 하나의 프로세스에 문제가 생겨도, 전체적인 프로그램은 동작합니다.
- 단점
- 프로세스 끼리는 공유하는 메모리가 없기 때문에, Context Switching 에 많은 비용이 발생합니다.
- 프로세스의 Context Switching 에는,
- 단순히 CPU 레지스터 교체 뿐만 아니라
- RAM과 CPU 사이의 캐쉬 메모리도 초기화되므로 오버헤드가 큽니다.
- 프로세스 끼리는 공유하는 메모리가 없기 때문에, Context Switching 에 많은 비용이 발생합니다.
멀티 쓰레드(Multi Thread)란?
- 개념
- 하나의 프로그램을 여러 개의 쓰레드로 구성하고, 각 쓰레드가 하나의 작업을 처리하는 것을 의미합니다.
- 프로세스는 한 개일수도, 여러 개일수도 있습니다.
- 하나의 프로그램을 여러 개의 쓰레드로 구성하고, 각 쓰레드가 하나의 작업을 처리하는 것을 의미합니다.
- 장점
- 자원의 효율성 증대
- 많은 프로세스를 생성함으로써 각 프로세스에 자원을 할당하는 작업(시스템 콜)이 줄어듭니다.
- Context Switching 처리 비용 감소
- 쓰레드는 프로세스 메모리의 코드/데이터/힙 영역을 공유하고 있으므로,
- Context Switching 이 발생할 때, Stack 영역만 처리하면 됩니다.
- 응답 속도 향상
- 쓰레드는 프로세스 메모리의 코드/데이터/힙 영역을 공유하고 있으므로,
- 프로세스 간의 통신(IPC)보다 쓰레드 간의 통신의 응답 속도가 빠릅니다.
- 자원의 효율성 증대
- 단점
- 쓰레드 하나에 문제가 생기면, 모든 프로세스가 종료됩니다.
- 자원을 공유하기 때문에 필연적으로 동기화 문제가 발생합니다.
- 쓰레드의 스케줄링은 운영체제가 관리하지 않기 때문에,
- 동기화 문제를 해결하기 위해, 프로그래머의 주의 깊은 설계가 필요합니다.
멀티 쓰레드를 사용하는 이유
- 자원의 효율성이 증가하고
- Context Switcing 비용이 감소하고
- 응답 속도가 빨라집니다.
동기화 문제(Synchronization Issue)란?
- 쓰레드는 프로세스의 코드/데이터/힙 영역을 공유하므로,
- 여러 쓰레드가 함께 공유 변수를 사용할 경우, 발생할 수 있는 충돌을 동기화 문제라고 합니다.
- 만약 A 쓰레드가 어떤 공유 변수를 사용하다가, B 쓰레드로 제어권이 넘어가고
- B 쓰레드가 해당 공유 변수를 수정한 뒤, 다시 A 쓰레드로 제어권이 넘어갔을 때
- A 쓰레드는 바뀐 자원으로 인해 오류가 발생할 수 있습니다.
- 쓰레드의 스케줄링은 운영체제가 관리 해주지 않기 때문에, 프로그래머가 적절한 기법을 직접 구현해야합니다.
- 따라서, 멀티 쓰레드를 사용하려면 신중해야합니다.
쓰레드 세이프(Thread Safe)란?
- 멀티 쓰레드 프로그래밍에서, 어떤 공유 자원에 여러 쓰레드가 동시에 접근해도, 프로그램 실행에 문제가 없는 상태를 의미합니다.
- Thread Safe 를 지키기 위한 방법은 네 가지로 이루어져있습니다.
- Mutual exclusion (상호 배제)
- 공유자원에 하나의 Thread 만 접근할 수 있도록, 세마포어/뮤텍스로 락을 통제하는 방법입니다.
- 일반적으로 많이 사용되는 방식입니다.
- 적용 예제
- Python 은 Thread Safe 하게 메모리 관리 하지 않으므로,
- GlL(Global Interpreter Lock)을 사용해 Thread Safe 를 보장합니다.
- 공유자원에 하나의 Thread 만 접근할 수 있도록, 세마포어/뮤텍스로 락을 통제하는 방법입니다.
- Atomic operation (원자 연산)
- 공유자원에 원자적으로 접근하는 방법입니다.
- Atomic
- 공유 자원 변경에 필요한 연산을 원자적으로 분리한 뒤,
- 실제로 데이터의 변경이 이루어지는 시점에 Lock 을 걸고,
- 데이터를 변경하는 시간 동안, 다른 쓰레드의 접근이 불가능하도록 하는 방법입니다.
- Thread-local storage (쓰레드 지역 저장소)
- 공유 자원의 사용을 최대한 줄이고, 각각의 쓰레드에서만 접근 가능한 저장소들을 사용함으로써 동시 접근을 막는 방법입니다.
- 일반적으로 공유상태를 피할 수 없을 때 사용하는 방식입니다.
- Re-entrancy (재진입성)
- 쓰레드 호출과 상관 없이 프로그램에 문제가 없도록 작성하는 방법입니다.
- Mutual exclusion (상호 배제)
참고
'Operating System > Concept' 카테고리의 다른 글
[OS] 쓰레드 세이프(Tread Safe)란? (0) | 2022.06.18 |
---|---|
[Memory] 코드, 데이터, 스택, 힙 영역 (0) | 2021.08.18 |
Comments