프로세스는 실행 중인 프로그램
운영체제에서 각 프로세스는 독립된 메모리 공간(코드, 데이터, 힙, 스택 영역 등)을 가진다.
운영체제는 프로세스 간의 자원 충돌을 방지한다.
각 프로세스는 자신만의 주소 공간을 가지고 있기 때문에 다른 프로세스의 메모리와 직접적인 상호작용이 불가능하다.
스레드는 프로세스 내에서 실행되는 작은 실행 단위
프로세스는 최소 하나의 스레드를 가지고 있다.
멀티스레드 프로세스는 여러 스레드를 통해 작업을 병렬로 수행할 수 있다.
같은 프로세스 내의 스레드는 코드, 데이터, 힙 영역을 공유하고 각자의 스택을 갖는다.
프로그램의 실행 코드가 저장
불변 데이터를 포함하며, 보통 읽기 전용으로 설정
예시: int main() { ... }
와 같은 프로그램 코드 자체.
전역 변수와 정적 변수가 저장
프로그램이 시작할 때 할당되며 프로그램이 종료될 때까지 유지
예시: static int count = 0;
같은 변수.
동적 메모리 할당이 이루어지는 곳입니다. malloc(), calloc(), new 등으로 메모리가 할당되며, 명시적으로 해제 (free(), delete)해주어야 한다
프로그램이 실행 중 필요에 따라 크기가 변할 수 있다.
예시: int* ptr = (int*) malloc(sizeof(int));
같은 코드에서 메모리 할당.
함수 호출 시 생성되는 지역 변수와 매개변수가 저장
함수 호출 시 스택 프레임이 쌓이고, 함수가 종료되면 해당 스택 프레임이 제거
예시: 함수 내의 int a = 5;
같은 지역 변수.
하나의 프로세스가 CPU를 사용 중인 상태에서 다른 프로세스가 CPU를 사용하도록 하기 위해, 이전의 프로세스의 상태(context)를 보관하고 새로운 프로세스의 상태를 적재하는 작업
즉, CPU/코어에서 실행중이던 프로세스/스레드가 다른 프로세스/스레드로 교체되는 것이다.
이는 멀티태스킹을 가능하게 하여 여러 프로세스나 스레드가 마치 동시에 실행되는 것처럼 보이도록 한다.
스레드가 CPU/코어에서 실행되는 기본 단위이기 때문에 1개의 프로세스는 1개의 스레드를 가지고 있다.
그러므로 컨텍스트(context)는 프로세스/스레드의 상태를 말한다.
컨텍스트 스위칭은 CPU의 상태(context)를 저장하거나 복원할 때 시간이 소요되며
다른 프로세스로 전환될 때 캐시 메모리를 사용할 수 없어서 성능 저하가 일어날 수 있다.
따라서 필요 이상으로 사용할 경우 오버헤드가 일어나서 오히려 성능 저하를 일으킨다.
스레드 간의 컨텍스트 스위칭에서는 스레드가 동일한 프로세스 내의 메모리 공간을 공유하기 때문에 스택 및 레지스터 같은 일부 컨텍스트만 저장하고 복원하면 되기 때문에 비용이 적으나
프로세스 간의 컨텍스트 스위칭은 메모리 공간을 포함한 전체 컨텍스트를 저장하고 복원해야하기 때문에 더 많은 비용을 요구한다.
따라서 멀테스레드를 사용하거나 스케쥴링 알고리즘, 작업 그룹화 등을 이용해 컨텍스트 스위칭을 최소화하는 것이 좋다.
컨텍스트 스위칭이 일어날 때 기본 동작으로
두 가지가 있다.
두 개 이상의 스레드나 프로세스가 동시에 같은 자원에 접근하여 데이터를 변경하려고 할 때, 실행 순서에 따라 결과가 달라지는 상황
레이스 컨디션을 방지하기 위해 사용하는 동기화 개념
Mutual Exclusion의 약자로, 한 번에 하나의 스레드만 임계 구역에 접근할 수 있도록 제어하는 잠금 메커니즘
작동 방식
스레드가 임계 구역에 들어가기 전에 뮤택스를 잠근다.
임계 구역을 벗어날 때 뮤택스를 해제하여 다른 스레드가 접근할 수 있게 한다.
특징
소유권: 잠금을 요청한 스레드만이 잠금을 해제할 수 있다.
만약 소유한 스레드가 잠금을 해제하지 않으면 교착 상태(Deadlock)가 발생할 수 있습니다.
특정 자원에 대해 여러 스레드가 접근할 수 있도록 허용하는 메커니즘
작동 방식
세마포어는 내부적으로 카운터를 유지한다. 카운터가 0보다 크면 스레드가 접근할 수 있고, 스레드가 자원에 접근할 때마다 카운터를 감소시킨다.
자원을 해제하면 카운터가 증가합니다.
특징
동시성 제어: 여러 스레드가 접근할 수 있는 동시성을 제어하는 데 사용된다.
비소유권: 세마포어는 특정 소유권 개념이 없으므로, 자원을 해제하는 것은 접근한 스레드가 아니어도 가능하다.
두 개 이상의 프로세스나 스레드가 서로가 보유한 자원을 기다리며 영원히 대기하는 상황
상호 배제(Mutual Exclusion)
점유와 대기(Hold and Wait)
비선점(Non-preemption)
순환 대기(Circular Wait)
자원 할당 순서
점유와 대기 방지
타임아웃(Timeout)