프로그램, 프로세스, 스레드
프로세스와 스레드의 정의를 먼저 알아보자.
프로세스(Process): 운영체제로부터 자원을 할당받은 작업의 단위
스레드(Thraed) : 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위
먼저 프로세스와 스레드에 대해 이해하기 전에 프로그램을 이해해야한다.
프로그램(Program): 파일이 저장 장치에 저장되어 있지만 메모리에는 올라가 있지 않은 정적인 상태
한마디로 운영체제가 메모리 공간을 할당해주지 않은 것이 프로그램이며 정적인 상태는 실행되지 않고 가만히 있다는 뜻이다.
결론은 프로그램은 아직 실행되지 않은 파일 그 자체를 가리키는 말이다. 예를 들면 우리가 자주사용하는 크롬, 카카오톡 등 사용자가 눌러서 실행하기 전의 상태를 말한다.
우리가 그 프로그램을 실행 시키면 컴퓨터 메모리상에 올라가게 되고, 이 상태를 동적인 상태라고 하며 이 상태의 프로그램을 프로세스라고 한다. 스케줄링 단계에서의 작업과 같은 단어라고 봐도 무방하다.
Ctrl + Shift + esc -> 프로세스 탭을 들어가면 쉽게 확인 가능하다. 실행중인 상태의 프로그램을 확인할 수 있고 동적인 상태인 Google Chrome가 프로세스이다. 만약 작업을 종료시키면 다시 프로그램이 되는것이다.
시간이 지날 수록 프로그램은 복잡해지고 프로세스 하나만으로 사용해서 프로그램을 실행하기는 제약이 너무 많아졌다. 그러면 프로세스를 여러 개 만들면 되지 않을까? 라고 생각을 할 수 있지만 운영체제는 안전성을 위해 프로세스마다 자신에게 할당된 메모리 내의 정보에만 접근할 수 있도록 제약을 두었다. 예를 들어 엑셀에서 작성한 표 데이터를 카카오톡 대화창에 자동으로 입력하고 싶다해서 엑셀이 직접 카카오톡 메모리에 접근하는 것은 불가능하다. 이처럼 각 애플리케이션이 독립된 프로세스로 실행되며 서로의 메모리 공간에는 접근할 수 없도록 운영체제가 보호하고 있다
실제로 프로그램 하나가 단순히 한 가지 작업만을 하는 경우는 드물다. 예를 들어 웹브라우저를 생각해보면 브라우저는 단순히 HTML을 렌더링 하는것만으로 끝나지 않는다. 이미지 로딩, 자바스크립트 실행, 사용자 입력 처리, 네트워크 통신 등 다양한 작업이 동시에 이뤄진다. 이처럼 다양한 작업을 동시에 수행하려면, 하나의 프로세스만으로는 부족하므로 하나의 프로세스 안에서 작업 단위를 동시에 실행할 수 있게 한 것이 스레드이다.
프로세스에 대해서 더 알아보자...
프로세스의 구조
- CODE: 프로그램의 컴파일된 기계어 코드가 저장되는 영역이다. 수정은 불가능하며 실행 중인 함수들의 명령어들이 이 영역에서 실행된다.
- DATA: 전역변수 또는 정적 변수 중 초기값이 있는 변수들이 저장된다. 프로그램이 시작될 때 메모리에 로드되며 종료 시까지 유지된다.
- BSS: DATA 영역과 함께 구성되며 초기값이 없는 전역/정적 변수가 저장된다. 실제로 실행 파일에는 크기만 기록되고 실행 시 0으로 초기화되어 메모리에 할당된다.
- STACK: 함수 호출시 지역 변수, 매개변수, 반환 주소 등이 저장되는 영역이다. 함수가 호출되면 스택 프레임(Stack Frame)이 생성되고 함수가 끝나면 제거된다.
- HEAP: 실행 중에 할당되는 메모리가 저장된다. 프로그래머가 직접 할당/해제를 해야 하며(C의 경우) 해제하지 않으면 메모리 누수가 발생한다. 자바의 경우는 가비지 컬렉터(GC)가 사용하지 않는 객체를 감지하고 정리한다.
스택 프레임(Stack Frame)이란?
Stack Frame은 함수가 호출될 때 스택에 쌓이는 데이터 블록으로 해당 함수의 지역 변수, 매개변수, 리턴 주소, 이전 함수의 상태 등을 담고있다.
왜 필요한데?
프로그램이 여러 함수를 호출하면 함수마다 자신의 실행 정보를 따로 저장해야한다. 그래야 함수가 끝났을 때 이전 상태로 정확히 돌아갈 수 있다.
스택을 사용하는 이유는 후입선출(LIFO)구조이기 때문이다. 마지막에 호출된 함수가 가장 먼저 끝나야 하니까 스택이 함수 호출과 복귀에 맞는 구조이다.
코드 예시
작성자는 주 언어인 JAVA위주로 설명하였다.
CODE 영역: 컴파일된 바이트코드 (JVM에서 네이티브 명령어로 실행) 수정 불가, 클래스, 메서드 등 실행 가능한 코드가 저장된다.
public class A {
public static void Hello() {
System.out.printLn("Hello World!!!");
}
}
Hello() 메서드는 JVM이 실행 가능한 바이트코드로 변환되어 CODE 영역에 저장되며 메서드는 JVM이 메모리에 로드한 후 이 영역에서 실행된다.
바이트 코드란?
바이트코드(Byercode)는 가상 머신(Virtual Machine)이 이해하고 실행할 수 있도록 컴파일된 중간 단계의 이진 코드이다.
1. .java 파일에 코드를 작성한다.
2. 컴파일하면 -> .class 파일이 생기는데, 이 안에 들어있는 것이 바이트 코드이다.
3. 이 바이트 코드를 JVM(Java Virtual Machine)이 실행한다.
바이트 코드는 운영체제나 CPU에 종속되지 않고 가상 머신에서 실행할 수 있도록 만들어진 코드이다.
바이트 코드는 이식성과 보안, 안정성, 성능과 같은 이점에서 사용한다. 어떠한 운영체제서든 실행가능하며 가상머신 위에서 실행되므로 실제 시스템에 영향을 덜 준다.
DATA(BSS) 영역: 초기값이 있는 static 변수, final 상수 그리고 초기값이 없는 static 변수를 함께 저장한다.
public class Ex {
static int count = 10; // DATA 영역
static final String APP_NAME = "MyApp"; // 역시 DATA 영역
static int value; // 초기값 X → 0으로 자동 초기화됨 (자바에서는 BSS와 DATA 구분 없음)
}
count와 APP_NAME은 클래스가 로딩될 때 JVM에 의해 메모리에 고정 배치된다. 초기값이 존재하므로 DATA 영역에 저장된다.
자바에서는 BSS 영역이 따로 없다. 초기값이 라도 JVM이 자동으로 0 또는 null로 초기화 한다.
STACK 영역: 지역변수, 매개변수, 함수 호출 정보를 저장한다. 함수가 호출될 때마다 스택 프레임 생성, 종료되면 제거된다.
public class Ex {
public static void main(String[] args) {
int local = 5; // STACK 영역
printValue(local);
}
public static void printValue(int val) { // val도 STACK에 저장
System.out.println(val);
}
}
HEAP 영역: 동적 할당된 객체가 저장되는 공간이다. new연산자로 생성된 인스턴스가 저장되며 자바에서는 GC가 자동으로 메모리 관리한다.
public class Ex {
public static void main(String[] args) {
Person p = new Person("Alice"); // HEAP에 Person 객체 생성
}
}
class Person {
String name;
Person(String name) {
this.name = name;
}
}
new Person("Alice")로 생성된 객체는 HEAP 영역에 저장, p는 STACK에 저장된 참조 변수이며 객체 내부 필드 name도 HEAP에 저장된다.
메모리 영역을 알고 있으면 더 효율적이고 안정적인 코드를 작성하며 문제를 더 잘 디버깅할 수 있는 장점이 있다. 눈에 보이지 않는 프로그램의 내부 동작을 시각화할 수 있게 되고, 더 깊은 사고를 가능하게 한다!!!
프로세스 상태 전이와 문맥교환
운영체제에서 프로세스는 실행되는 동안 여러 상태를 거친다. 이 상태들을 프로세스의 생명 주기를 나타내며 각 상태 간의 이동을 프로세스 상태 전이라고 한다. 프로세스 상태 전이는 운영체제가 CPU, 메모리 등의 자원을 효율적으로 관리하고 여러 프로세스가 동시에 실행되는 것처럼 보이게 하는 핵심 개념이다.
주요 프로세스 상태
- 생성(New): 프로세스가 처음 생성되는 상태, 이 상태에서 운영체제는 프로세스를 실행하기 위한 자원을 할당한다.
- 준비(Ready): 프로세스가 CPU를 할당 받아 실행될 준비가 된 상태, CPU 스케줄러가 다음 실행할 프로세스를 선택하기 위해 대기하는 큐에 포함된다.
- 실행(Running): 프로세스가 CPU를 할당받아 명령어를 실행하고 있는 상태, 한 번에 하나의 프로세스만 이 상태에 있을 수 있으나 멀티 코어 시스템에서는 코어 수만큼 할당 가능하다.
- 대기(Waiting/Blocked): 프로세스가 I/O 작업 완료, 특정 이벤트 발생, 자원 할당 등과 같은 특정 조건을 기다리는 상태, 이 상태에서는 CPU를 사용하지 않는다.
- 종료(Terminated): 프로세스가 실행을 완료했거나 어떤 이유로든 중단되어 메모리에서 제거되기 전의 상태
주요 상태 전이
1. 생성 -> 준비 : 프로세스가 생성되고 필요한 자원을 할당받으면 CPU를 할당받기 위해 준비 큐로 이동
2. 준비 -> 실행 : CPU 스케줄러가 준비 큐에 있는 프로세스 중 하나를 선택하여 CPU를 할당하면 해당 프로세스는 실행 상태로 전이
3. 실행 -> 대기
- I/O 요청 : 파일 읽기/쓰기와 같은 I/O 작업을 요청하면, I/O 작업이 완료될 때까지 대기 상태로 전이
- 자원 요청 : 프로세스가 사용 불가능한 자원(프린터 등)을 요청하면, 해당 자원이 사용가능 해질 때까지 대기 상태로 전이
- 이벤트 대기 : 특정 이벤트를 기다려야 하는 경우 대기 상태로 전이
4. 실행 -> 준비
- 타임 슬라이스 만료(Time Slice Expired): 시분할 시스템에서 프로세스에 할당된 CPU 사용 시간이 만료되면 강제로 CPU를 빼앗기고 준비 상태로 돌아가 다음 차례를 기다림
- 인터럽트 (Interrupt) : 우선순위가 높은 인터럽트가 발생하면 현재 실행 중인 프로세스 중단되고 준비 상태로 돌아감
- 우선순위가 더 높은 프로세스 : 선점형 스케줄링에서 더 높은 우선순위의 프로세스가 준비 큐에 들어오면, 현재 실행 중인 프로세스는 중단되고 준비 상태로 돌아감
5. 대기 -> 준비 : 프로세스가 대기하던 I/O 작업이 완료되거나 요청했던 자원이 할당되거나 기다리던 이벤트가 발생하면 다시 CPU를 할당받을 준비를 위해 준비 상태로 전이
6 실행 -> 종료 : 프로세스가 할당된 작업을 모두 완료하거나 오류가 발생하거나 외부적인 요인(프로세스 강제종료, kill 시그널)에 의해 중단되면 종료 상태로 전이
7. 준비 -> 종료 : 비정상적인 상황으로 인해 준비 상태에 있던 프로세스가 강제로 종료될 수 있음
문맥교환 (Context Switching)
문맥 교환은 특정 프로세스 상태 전이가 일어날 때 동반되는 작업인데 CPU를 사용하는 주체가 변경될 때마다 발생하는 것이 문맥 교환이다. 한마디로 CPU가 다른 프로세스에게 점유되는 상황이라고 할 수 있으며 CPU의 제어권이 한 프로세스에서 다른 프로세스로 넘어가는 과정이라고 할 수 있다. CPU가 Google Chrome를 실행하고 있을 때 타임 슬라이스 만료로 카카오톡이 CPU를 선점하면 Google Chorme 프로세스의 문맥을 PCB(Process Control Block)에 저장하고 준비 큐에서 다음으로 실행할 프로세스를 선택한다. 그 후 선택된 프로세스의 문맥을 복원하여 CPU 에 로드하고, 해당 프로세스의 실행을 재개한다. 이 과정이 문맥 교환이다. 다시 한 번 되새겨보자면 프로세스는 동시에 실행되는 것이 아닌 동시에 실행되는 것처럼 보이는 것이다.
인터럽트 (Interrupt)가 뭔데?
CPU가 프로그램을 실행하고 있을 때, 현재 실행 중인 작업을 잠시 중단하고 다른 특정 작업을 수행하도록 하는 메커니즘이다. 사람이 일하다가 전화오면 하던 일을 멈추고 전화를 하는 것과 같다.
타임 슬라이스 (Time Silce /Quantum)가 뭔데?
시분할 시스템에서 CPU가 한 프로세스에 할당되는 최대 시간 단위를 의미한다. 쿼텀(Quantum)이라고도 한다.
PCB(Process Control Block)이 뭔데?
운영체제가 특정 프로세스를 관리하고 제어하기 위해 필요한 모든 정보를 담고 있는 데이터 구조이다. 문맥 교환 발생시 Google Chrome 프로세스가 어디까지 실행했는지 어떤 자원을 사용하고 있었는지 정확히 알아야 다시 이 프로세스를 실행 할 때 중단되었던 시점부터 이어서 처리할 수 있다.
PCB의 주요정보
- 프로세스 식별자 (Process ID - PID) : 각 프로세스를 고유하게 식별하는 번호
- 프로세스 상태 (Process State) : 프로세스의 현재 상태 (생성, 준비 실행, 대기, 종료)
- 프로그램 카운터 (Program Counter - PC) : 이 프로세스가 다음에 실행할 명령어의 주소, 프로세스가 일시 중단되었다가 다시 실행될 때 이 정보를 통해 중단된 지점부터 이어서 실행함
- CPU 레지스터 정보 (CPU registers) : CPU 내부에 있는 범용 레지스터, 스택 포인터, 인덱스 레지스터 등 모든 레지스터 값을 저장, 문맥 교환 시 프로세스의 레지스터 값을 PCB에 저장하고, 다음 프로세스의 레지스터 값을 복원하는데 사용
- CPU 스케줄링 정보 : 프로세스의 우선순위, 스케줄링 큐에서의 위치, CPU 사용 시간, 최종 실행 시간 등 CPU 할당과 관련된 정보
- 메모리 관리 정보 : 프로세스의 가상 주소 공간에 대한 정보
- 계정 정보 (Accounting Information) : CPU 사용 시간, 실제 사용 시간, 프로세스 ID, 소유자 정보 등 프로세스의 자원 사용 통계 및 관리에 필요한 정보
- 입출력 상태 정보 (I/O Status Infomation) : 프로세스에 할당된 입출력 장치 목록, 열린 파일 목록 등 입출력 관련 정보
- 포인터 : 부모 프로세스, 자식 프로세스, 다음 PCB의 주소 등 프로세스 간의 관계나 연결된 데이터 구조를 가리키는 포인터 정보
PCB의 주요정보는 커널(Kernel) 영역의 메모리에 저장된다. 일반 사용자는 직접 접근 할 수 없도록 보호하며 운영체제는 이 PCB들을 효율적으로 관리하기 위해 프로세스 테이블이라는 자료구조(연결리스트 or 배열 형태)를 사용하요 PCB에 대한 포인터를 저장한다.
PCB는 프로세스를 생성, 실행, 중단, 재개, 종료 등 생명 주기를 관리하는 키 카드이며 DB라고 할 수 있음, 문맥 교환시 이 PCB에 저장된 정보들이 사용된다.
추후에 프로세스 스케줄링을 포스팅할 예정. 프로세스 스케줄링은 CPU를 어떤 프로세스에 할당할 것인가 결정하는 과정이며 한정된 자원을 여러 프로세스들이 효율적으고 공정하게 공유할 수 있도록 하는 작업이다. 프로세스 스케줄링을 이해하기 전에 프로세스 상태 전이를 기억하고 있으면 더욱 좋음!
프로세스와 스레드의 작동방식
프로세스가 메모리에 올라갈 때 운영체제로부터 시스템 자원을 할당받는다. 운영체제는 프로세스마다 각각 독립된 메모리 영역을 Code, Data, Stack, Heap의 형식으로 할당 해주는데 각각 독립된 메모리 영역을 할당해주기 때문에 프로세스는 다른 프로세스의 변수나 자료에 접근할 수 없다.
하지만 스레드는 메모리를 서로 공유할 수 있다 프로세스가 할당받은 메모리 영역 내에서 Stack 형식으로 할당된 메모리 영역은 따로 할당 받고, 나머지 Code, Data, Heap 형식으로 할당된 메모리 영역을 공유한다. 각각의 스레드는 별도의 스택을 가지고 있지만 힙 메모리는 서로 읽고 쓸 수 있게 된다.
여기서 중요한 차이를 알 수 있는데 프로세스를 실행하다가 오류가 발생해서 프로세스가 강제로 종료되면 다른 프로세스에게 별 다른 영향을 주지 않지만, 스레드는 Code, Data, Heap 영역을 공유하기 때문에 어떠한 스레드 하나에 오류가 발생하면 같은 프로세스 내의 다른 모든 스레드가 종료된다.
멀티프로세싱, 멀티스레딩
멀티 프로세싱(Multi-processing)
멀티 프로세싱은 둘 이상의 프로세스를 사용하고 두 개 이상의 프로세스를 동시에 실행하는 것을 의미한다. '동시에' 말 그대로 병렬적으로 실행된다는 의미이다. 각각의 프로세스는 운영체제로 부터 독립적인 메모리 공간(코드, 데이터, 힙 스택)과 자원(파일 핸들, 열린 소켓)을 할당 받는다. 따라서 한 프로세스의 요류나 종료가 다른 프로세스에 직접적인 영향을 미치지 않는다.
구현 방식
- 다중 CPU 시스템 : 물리적으로 여러 개의 CPU를 장착한 시스템
- 멀티 코어 시스템 : 하나의 CPU 칩 내부에 여러 개의 처리 코어(Core)가 있는 시스템. 현대의 대부분의 CPU가 해당
장점
- 안정성 (Fault Isolation) : 각 프로세스가 독립적인 메모리 공간을 가지므로 프로세스 하나가 문제가 생겨도 다른 프로세스에는 영향을 주지 않아 시스템 전체의 안정성이 높다
- 병렬성 (Parallelism) : 여러 개의 CPU 코어를 효과적으로 화룡ㅇ하여 동시에 여러 작업을 처리할 수 있어서 CPU 연산량이 많은 작업에서 높은 성능 향상을 보인다.
- 자원 관리 용이 : 각 프로세스가 독립적이므로, 운영체제 입장에서는 자원 할당 및 회수가 명확하다.
단점
- 높은 자원 소모: 각 프로세스가 독립적인 메모리 공간과 자원을 가지므로 스레드에 비해 더 많은 메모리와 시스템 자원을 필요로 한다.
- 느린 문맥교환 : 프로세스간 문맥 교환은 스레드간 문맥교환보다 훨씬 많은 정보를 저장하고 복원해야 하므로 오버헤드가 크고 속도가 느리다.
- 복잡한 IPC : 프로세스 간에 데이터를 주고 받으려면 파이프, 소켓, 공유 메모리 등 운영체제가 제공하는 복잡한 IPC 메커니즘을 사용해야 한다.
오버헤드 (Overhead)가 뭔데?
어떠한 작업을 수행하는 데 필수적이지는 않지만 그 작업을 가능케 하거나 효율적으로 만들기 위해 소모되는 자원을 말한다. 시간, 메모리, CPU 사이클 등 의미한다. 문맥교환시 상태를 저장하고 불러오는 데 드는 시간은 문맥 교환 오버헤드, 함수를 호출하고 리턴하는 가정에서 스택에 변수를 푸시하고 팝하며 함수 주소로 점프하는 등 추가적인 CPU 사이클이 도는 시간등이 해당된다.
과도한 오버헤드는 시스템의 성능을 저하시키는 원인이 된다. 하지만 과도하게 성능을 강조하다보면 보안이 취약해지므로 적절하게 균형을 잡는 것이 중요하다.
IPC(Inter-Process Communication)가 뭔데?
각 프로세스는 독립적으로 존재하므로 프로세스들이 메모리 영역에 함부로 접근하지 못하지만 그 프로세스들이 정보를 주고받거나 작업을 조율해야 할 필요가 생긴다. 이처럼 독립적인 프로세스들이 서로 데이터를 교혼하고 활동을 동기화하기 위한 메커니즘이며 게임에서 서버 프로세스와 클라이언트 프로세스가 서로 게임 상태를 주고 받거나 파일 복사 프로세스가 다른 파일 관리 프로세스에게 복사 완료를 알릴 때 사용한다. 이것을 프로세스 간 통신, IPC라고 한다.
프로세스는 독립적이고 고립된 환경에서 실행되기 때문에 전반적인 시스템의 유연성과 확장성을 높이려면 프로세스간 협업이 필요하기 때문에 주로 사용된다.
주요 목적은 정보 공유, 계산 가속화, 모듈성, 편의성을 위해 사용되며 IPC의 종류에는 Pipe, Message Queue, Shared Memory, Semaphore등이 있다.
멀티 스레딩(Multi-threading)
멀티 스레딩은 하나의 프로세스 내에서 둘 이상의 스레드를 사용하여 갖겁을 동시에 수행하는 것을 의미한다. CPU 코어 수에 따라 병렬적일 수 도 있고 단일 코어에서는 동시적(Concurrent)으로 번갈아 가며 실행될 수 있다.
하나의 프로세스는 하나이상의 스레드를 가질 수 있고 같은 프로스세 내의 스레드들은 프로세스의 코드, 데이터, 힙 영역과 같은 대부분의 자원을 공유하지만 각각 독립적은 Stack과 Register 값을 가진다.
구현 방식
- 운영체제 커널이 직접 스레드를 관리하는 커널 수준 스레드(Kernel-level-Threads) 방식이 주로 사용된다.
- 단일 CPU 코어에서도 시분할 방식으로 스레드 간 문맥 교환이 빠르게 일어나 여러 작업이 동시에 진행되는 것처럼 보이게한다.
장점
- 자원 효율성 : 같은 프로세스 내의 스레드들이 대부분의 자원을 공유, 프로세스를 새로 생성하는 것 보다 훨씬 적은 메모리와 시스템 자원을 소모한다.
- 빠른 문맥 교환 : 스레드 간 문맥 교환은 프로세스 간 문맥 교환보다 저장하고 복원할 정보가 적기 때문에 오버헤드가 적고 속도가 빠르다.
- 빠른 스레드 간 통신 : 스레드 들이 프로세스의 힙 영역이나 전역 변수 같은 메모리 공간을 공유하므로 별도의 IPC 메커니즘 없이 직접 데이터를 주고바다을 수 있어서 통신 비용이 낮다.
- 응답성 향상 : 하나의 스레드가 긴 작업을 수행하더라도, 다른 스레드가 사용자 입력이나 다른 작업을 처리할 수 있어 프로그램의 응답성이 향사오딘다.
- 멀티코어 활용 : 멀티코어 CPU 환경에서 여러 스레드를 병렬적으로 실행하여 성능이 향상된다.
단점
- 동기화 문제(Synchronization Issues): 여러 스레드가 공유 자원에 동시에 접근할 경우 데이터 손상이 발생할 수 있다. 이를 방지하기 위해 Mutex, Semaphore 등 복잡한 동기화 메커니즘을 사용하며, 이 과정에서 Deadlock과 같은 문제가 발생할 수 있다.
- 안정성 취약 : 하나의 스레드가 문제가 발생하여 비정상적으로 종료되면 해당 프로세스가 공유하는 자원을 사용하는 프로세스들의 영향을 미쳐 프로세스 자체가 종료될 수 있다.
- 디버깅의 어려움 : 동시성 문제와 공유 자원으로 인한 버그는 디버깅이 까다롭다.
커널 수준 스레드 (Kernel-Level Thread)가 뭔데?
운영체제의 커널이 직접 관리하고 스케줄링하는 스레드이다. 쉽게 생각하면 운영체제가 개별 스레드의 존재를 인지하고 직접 제어하는 스레드이다.
커널 수준 스레드는 사용자 수준 스레드, 커널 수준 스레드로 나뉘는데
사용자 수준 스레드는 라이브러리 수준에서 구현되며 커널입장에서는 하나의 프로세스 내에서 단일 스레드만 실행되는 것처럼 보인다. 커널 수준 스레드는 커널이 스레드를 직접 생성하고 관리하며 각 스레드는 커널이 관리하는 독립적인 실행 단위로 간주한다. 주로 Windows, Linux, macOS 등에서 사용되는 스레드 모델이다.
데드락 (Deadlock)이 뭔데?
여러 프로세스 또는 스레드가 서로가 가지고 있는 자원을 기다리면서 영원히 다음 작업을 진행하지 못하고 멈춰 있는 상태를 의미
데드락이 발생하는 4가지 조건은 상호 배제, 점유와 대기, 비선점, 순환 대기 등이 있다.
멀티프로세싱은 하나의 운영체제 안에서 여러 프로세스가 실행되는 것을 의미하지만 자세원 원리를 알아보면 동시에 실행되는 것처럼 보이게 하는 운영체제의 프로세스 스케줄링 방식에 의해 설명될 수 있다.
멀티프로세싱은 하나의 운영체제 안에서 여러 프로세스가 실행되는 것이고, 멀티스레드는 하나의 프로세스가 여러 작업을 여러 스레드를 사용해 동시에 처리하는 것을 말한다.
'Operating System' 카테고리의 다른 글
운영체제(Operating System)란? (2) | 2025.05.30 |
---|