Operating SystemJun 18, 2025

Process & Thread

Process & Thread

프로세스와 스레드

프로세스는 컴퓨터에서 실행되고 있는 프로그램을 말하며 CPU 스케줄링의 대상이 되는 작업(task)이라는 용어와 거의 같은 의미로 사용된다. 스레드는 프로세스 내에서 실행되는 작업의 단위로, 프로세스는 하나 이상의 스레드를 가질 수 있다. 이 글에서는 프로세스와 스레드의 개념, 차이점, 그리고 운영 체제에서의 역할에 대해 알아보자.



목차



프로세스와 컴파일 과정

프로세스는 프로그램이 메모리에 올라와 인스턴스화된 상태를 의미한다. 예를 들어 프로그램은 구글 크롬 프로그램(chrome.exe)이고 이를 두 번 클릭하면 구글 크롬 프로세스가 실행된다. C언어 기반의 프로그램을 컴파일러가 컴파일 과정을 통해 컴퓨터가 이해할 수 있는 기계어로 변환하여 실행할 수 있는 파일을 생성한다.


전처리

소스 코드의 주석을 제거하고 #include 등 헤더 파일을 병합하고 매크로를 치환하는 과정이다.


컴파일

소스 코드를 어셈블리어로 변환하는 과정이다. 이 과정에서 문법 오류가 있는지 검사하고, 최적화 작업을 수행한다.


어셈블

어셈블리어는 목적 코드(Object Code)로 변환된다. 목적 코드는 기계어로 변환되기 전의 중간 단계 코드이다.


링킹

링킹은 목적 코드를 실행 파일로 만드는 과정이다. 이 과정에서 내외부 라이브러리 함수, 다른 파일들, 목적 코드들을 연결하여 실행 가능한 파일을 생성한다.


정적 라이브러리와 동적 라이브러리 라이브러리는 프로그램에서 자주 사용되는 함수들을 모아놓은 파일이다. 라이브러리에는 정적 라이브러리와 동적 라이브러리가 있다.

  • 정적 라이브러리: 컴파일 시점에 라이브러리가 제공하는 모든 코드들을 실행 파일에 포함시키는 방식이다. 시스템 환경 등 외부 의존도가 낮은 장점이 있지만, 실행 파일의 크기가 커지고, 라이브러리의 수정이 필요할 때마다 다시 컴파일해야 하는 단점이 있다.
  • 동적 라이브러리: 실행 시점에 필요한 코드만 메모리에 로드하는 방식이다. 이 방식은 실행 파일의 크기를 작게 유지할 수 있고, 라이브러리의 수정이 필요할 때마다 다시 컴파일할 필요가 없지만, 시스템 환경 등 외부 의존도가 높아질 수 있다.


프로세스의 상태

프로세스는 여러 가지 상태 값을 가질 수 있다. 운영 체제는 프로세스의 상태를 관리하여 CPU 자원을 효율적으로 할당한다. 프로세스의 상태는 다음과 같다.


생성 상태(Created)

프로세스가 생성된 상태로, 아직 실행되지 않은 상태이다. 이 상태에서는 프로세스가 필요한 자원을 할당받고, 초기화 작업을 수행한다. fork(), exec() 등의 시스템 콜을 통해 프로세스가 생성된다. 이 때, PCB가 생성되어 프로세스의 정보를 담고 있다.

  • fork(): 현재 프로세스를 복제하여 새로운 자식 프로세스를 생성하는 시스템 콜이다. 주소 공간만을 복사하여 새로운 프로세스를 생성하며, 부모 프로세스와 자식 프로세스는 서로 독립적으로 실행된다.
  • exec(): 현재 프로세스의 주소 공간을 새로운 프로그램으로 대체하는 시스템 콜이다. 이 시스템 콜을 호출하면 현재 프로세스의 코드, 데이터, 스택 등이 새로운 프로그램으로 대체된다. exec()는 일반적으로 fork()와 함께 사용되어 자식 프로세스를 생성한 후 새로운 프로그램을 실행하는 데 사용된다.

준비 상태(Ready)

프로세스가 실행될 준비가 된 상태로, CPU를 할당받기 위해 대기 중인 상태이다. 이 상태에서는 프로세스가 CPU를 할당받을 때까지 기다린다.


준비 중단 상태(Ready Suspended)

프로세스가 준비 상태에 있지만, 메모리에서 스왑 아웃되어 디스크에 저장된 상태이다. 이 상태에서는 프로세스가 다시 메모리에 로드될 때까지 기다린다.


실행 상태(Running)

프로세스가 CPU를 할당받아 실행 중인 상태이다. 이 상태에서는 프로세스가 CPU를 사용하여 작업을 수행한다.


대기 상태(Blocked)

프로세스가 I/O 작업이나 다른 이벤트를 기다리는 상태이다. 이 상태에서는 프로세스가 CPU를 사용하지 않고, 해당 작업이 완료될 때까지 대기한다.


대기 중단 상태(Blocked Suspended)

프로세스가 대기 상태에 있지만, 메모리에서 스왑 아웃되어 디스크에 저장된 상태이다. 이 상태에서는 프로세스가 다시 메모리에 로드될 때까지 기다린다.


종료 상태(Terminated)

프로세스가 실행을 완료하고 종료된 상태이다. 이 상태에서는 프로세스가 사용하던 자원을 해제하고, PCB가 삭제된다. 종료 상태는 정상적으로 종료되는 상태도 있지만 비정상적으로 종료(abort, crash, kill, etc.)되는 경우도 있다.



프로세스의 메모리 구조

운영체제는 프로세스에 적절한 메모리를 할당한다. 프로세스는 위에서부터 아래로 스택, 힙, 데이터 영역, 코드 영역으로 구성된다. 스택은 아래에서 위로 성장하고, 힙은 위에서 아래로 성장한다.


스택(Stack)과 힙(Heap)

스택과 힙은 동적 할당이 되며, 동적 할당은 런타임에서 메모리를 할당하는 방식이다.

  • 스택: 지역 변수, 매개 변수, 함수 호출에 따라 메모리를 할당하고 해제하는 구조이다. 함수가 호출될 때마다 스택 프레임이 생성되고, 함수가 종료되면 해당 스택 프레임이 해제된다.
  • 힙: 동적으로 메모리를 할당하고 해제하는 구조로, 프로그래머가 직접 메모리를 관리한다. malloc(), calloc(), realloc(), free() 등의 함수를 사용하여 메모리를 할당하고 해제한다. 동적으로 관리되는 자료 구조의 경우 힙을 사용하여 메모리를 할당한다. 예를 들어 vector, map, set 등의 STL 컨테이너는 힙을 사용하여 메모리를 할당한다.

데이터 영역(BSS, Data segment)과 코드 영역(Code/Text segment)

이 영역은 정적 할당되는 영역이다. 정적 할당은 컴파일 시점에 메모리를 할당하는 방식이다. 데이터 영역은 BSS segmentData segment로 나뉘고 코드 영역은 Code/Text segment로 불린다.

  • BSS segment: 초기화되지 않은 전역 변수와 정적 변수를 저장하는 영역이다. 이 영역은 프로그램이 시작될 때 자동으로 0으로 초기화된다.
  • Data segment: 초기화된 전역 변수와 정적 변수를 저장하는 영역이다. 이 영역은 프로그램이 시작될 때 초기화된 값으로 설정된다.
  • Code/Text segment: 프로그램의 실행 코드가 저장되는 영역이다. 이 영역은 읽기 전용으로, 프로그램의 실행 중에 변경되지 않는다.


PCB

PCB(Process Control Block)는 운영체제에서 프로세스에 대한 메타데이터를 저장하는 구조체이다. 프로세스가 생성될 때 운영체제에 의해 생성되며, 프로세스가 종료될 때까지 유지된다. PCB는 프로세스의 중요한 정보를 포함하고 있기 때문에 사용자가 접근하지 못하도록 커널 스택의 가장 앞 부분에서 관리된다. 다음과 같이 프로세스의 상태, 프로세스 ID, 프로그램 카운터, 레지스터 값, 메모리 관리 정보 등을 포함한다.

PCB의 구조

  • 프로세스 스케줄링 상태: 프로세스의 현재 상태(생성, 준비, 실행, 대기, 종료 등)를 나타낸다.
  • 프로세스 ID(PID, Process ID): 프로세스의 고유 식별자이다. 운영체제는 프로세스를 식별하기 위해 프로세스 ID를 사용한다. 해당 프로세스의 ID 뿐 아니라 부모 프로세스의 ID(PPID, Parent PID)도 포함된다.
  • 프로세스 권한: 프로세스가 접근할 수 있는 자원에 대한 권한 정보를 포함한다.
  • 프로그램 카운터(PC, Program Counter): 다음에 실행될 명령어의 주소를 저장한다. 프로세스가 실행되는 동안 이 값이 변경된다.
  • 레지스터 값: 프로세스가 실행 중인 CPU 레지스터의 값을 저장한다. 이 값은 프로세스가 실행되는 동안 변경된다.
  • CPU 스케줄링 정보: 프로세스의 우선순위, 스케줄링 정책 등을 포함한다. 운영체제는 이 정보를 사용하여 CPU를 할당한다.
  • 계정 정보: 프로세스 실행에 사용된 CPU 사용량, 실행한 유저의 정보 등을 포함한다.
  • I/O 상태 정보: 프로세스에 할단됭 I/O 자원(파일, 네트워크 소켓 등)에 대한 정보와 상태를 포함한다.

컨텍스트 스위치(Context Switch)

컨텍스트 스위치는 PCB를 사용하여 프로세스 간의 전환을 수행하는 과정이다. 한 프로세스에 할당된 CPU 시간을 다 사용하거나, I/O 작업을 기다리는 등의 인터럽트가 발생하면 운영체제는 현재 실행 중인 프로세스의 상태를 PCB에 저장하고, 다음에 실행할 프로세스의 PCB를 불러와 해당 프로세스의 상태로 전환한다. 이 과정에서 CPU 레지스터, 프로그램 카운터, 스택 포인터 등의 정보를 PCB에 저장하고, 다음 프로세스의 PCB에서 해당 정보를 불러온다. 이렇게 함으로써 프로세스 간의 상태를 유지하고, CPU 자원을 효율적으로 관리할 수 있다.


병행(Concurrency) 실행 컴퓨터는 많은 프로그램을 동시에 실행하는 것처럼 보이지만, 한 시점에서 실행되고 있는 프로세스는 단 한 개이며, 많은 프로세스가 동시에 실행되는 것처럼 보이는 이유는 CPU가 빠르게 프로세스 간의 전환을 수행하기 때문이다. 현대의 컴퓨터는 8코어 이상의 멀티 코어 CPU를 사용하여 여러 프로세스를 동시에 실행할 수 있지만, 여전히 하나의 코어가 한 시점에 처리하고 있는 프로세스는 단 하나이다.


컨텍스트 스위치의 오버헤드(Overhead) 컨텍스트 스위치가 일어날 때 유휴 시간(idle time)이 발생한다. 이는 프로세스 간의 전환 과정에서 CPU가 다른 작업을 수행하지 못하는 시간을 의미한다. 이 유휴 시간은 컨텍스트 스위치의 오버헤드로, 프로세스 간의 전환이 빈번하게 일어날수록 유휴 시간이 증가한다. 캐시 미스 등 다른 요인도 유휴 시간을 증가의 원인이 될 수 있다. 이로 인해 CPU 자원의 효율적인 사용이 저해될 수 있다. 따라서 운영체제는 프로세스 간의 전환을 최소화하고, 유휴 시간을 줄이기 위해 다양한 스케줄링 알고리즘을 사용한다.


스레드에서의 컨텍스트 스위치 스레드는 프로세스 내에서 실행되는 작업의 단위로, 프로세스와 유사한 개념이다. 스레드는 프로세스의 자원을 공유하며, 프로세스 내에서 여러 스레드가 동시에 실행될 수 있다. 스레드 간의 컨텍스트 스위치는 프로세스 간의 컨텍스트 스위치보다 빠르다. 이는 스레드가 프로세스의 자원을 공유하기 때문에, PCB를 저장하고 불러오는 과정이 필요 없기 때문이다. 스레드 간의 컨텍스트 스위치는 레지스터 값, 프로그램 카운터, 스택 포인터 등의 정보만 저장하고 불러오는 것으로 충분하다. 이로 인해 스레드 간의 전환이 더 빠르게 이루어질 수 있다.



멀티 프로세싱

멀티 프로세싱(Multi Processing)은 여러 개의 '프로세스', 즉 멀티 프로세스를 통해 동시에 두 가지 이상의 작업을 수행하는 것을 의미한다. 이를 통해 하나 이상의 일을 병렬로 처리할 수 있으며 특정 프로세스에서 발생하는 오류가 다른 프로세스에 영향을 미치지 않도록 할 수 있다.


웹 브라우저

웹 브라우저는 멀티 프로세스 구조를 채택하고 있다.

  • 브라우저 프로세스: 브라우저의 UI를 담당하며, 탭과 창을 관리한다. 이 프로세스는 브라우저의 메인 프로세스로, 사용자 인터페이스와 관련된 작업을 수행한다.
  • 렌더러 프로세스: 각 탭마다 별도의 렌더러 프로세스가 생성되어 웹 페이지를 렌더링한다. 이 프로세스는 HTML, CSS, JavaScript 등을 처리하여 웹 페이지를 표시한다.
  • 플러그인 프로세스: 브라우저에서 사용하는 플러그인(예: Flash, PDF 뷰어 등)을 실행하는 프로세스이다. 이 프로세스는 플러그인의 기능을 제공하며, 브라우저의 메인 프로세스와 독립적으로 실행된다.
  • GPU 프로세스: 그래픽 처리 장치(GPU)를 사용하여 웹 페이지의 그래픽을 렌더링하는 프로세스이다. 이 프로세스는 GPU를 활용하여 그래픽 성능을 향상시킨다.

IPC(Inter-Process Communication)

IPC를 통해 프로세스 간의 통신을 수행할 수 있다. 클라이언트는 서버에 요청을 보내고, 서버는 클라이언트에게 응답을 보내는 방식으로 통신하는 것이 IPC의 대표적인 예이다. IPC의 종류로는 공유 메모리, 파일, 소켓, 익명 파이프, 명명 파이프, 메세지 큐 등이 있다.


공유 메모리(Shared Memory) 공유 메모리는 여러 프로세스가 동일한 메모리 공간을 공유하여 데이터를 주고받는 방식이다. 이 방식은 빠른 속도로 데이터를 전송할 수 있지만, 동기화 문제를 해결해야 한다. 기본적으로 각 프로세스는 다른 프로세스의 메모리에 접근할 수 없지만, 공유 메모리를 사용하면 여러 프로세스가 동일한 메모리 공간을 공유할 수 있다. IPC 방식 중 어떠한 매개체를 통해 데이터를 주고받는 것이 아니라, 메모리 공간을 직접 공유하여 데이터를 주고받아 가장 빠르게 데이터를 전송할 수 있다. 하드웨어 관점에서의 공유 메모리는 CPU가 접근할 수 있는 RAM을 가르키기도 한다.


파일(File) 파일은 디스크에 저장된 데이터를 읽고 쓰는 방식으로, 프로세스 간의 데이터를 주고받을 수 있다. 이 방식은 데이터의 영속성을 보장하지만, 속도가 느릴 수 있다


소켓(Socket) 소켓은 네트워크를 통해 데이터를 주고받는 방식으로, 프로세스 간의 통신을 가능하게 한다. 이 방식은 네트워크를 통해 데이터를 전송할 수 있어 원격 프로세스와의 통신이 가능하다. TCP와 UDP와 같은 네트워크 프로토콜을 사용하여 데이터를 전송한다.


익명 파이프(Anonymous Pipe) 익명 파이프는 부모 프로세스와 자식 프로세스 간의 통신을 위한 일방향 통신 채널이다. 이 방식은 간단한 데이터 전송에 적합하지만, 두 프로세스가 동일한 부모 프로세스를 가져야 한다는 제약이 있다. 익명 파이프는 pipe() 시스템 콜을 사용하여 생성할 수 있다. 아래는 익명 파이프(|)를 사용하여 실패 로그를 검색하는 예시이다.

bash
find /var/log -type f -name "*.log" \	# 검색할 로그 파일을 지정
	| xargs grep -H "fail" \			# "fail" 문자열이 포함된 로그 파일을 검색
	| sed 's/:.*$//' \					# grep 결과에서 파일 이름만 추출
	| sort \							# 파일 이름을 정렬
	| uniq								# 중복된 파일 이름 제거

명명 파이프(Named Pipe) 명명 파이프는 익명 파이프와 유사하지만, 이름을 가진 통신 채널이다. 이 방식은 서로 다른 프로세스 간의 통신을 가능하게 하며, 양방향 통신이 가능하다. 명명 파이프는 mkfifo() 시스템 콜을 사용하여 생성할 수 있다. 명명 파이프는 파일 시스템에 존재하는 파일처럼 동작하며, 여러 프로세스가 동시에 접근할 수 있다.

아래는 명명 파이프를 사용하여 프로세스의 실행 결과를 로그 파일에 기록하는 예시이다. 하나의 프로세스가 여러 개의 명명 파이프와 통신하는 단일 프로듀서 다중 컨슈머 패턴이다.

bash
# 1) FIFO 파일 생성
mkfifo /tmp/myservice.pipe
mkfifo /tmp/myservice.pipe.err

# 2) FIFO에서 들어오는 데이터를 로그 파일에 append
tee -a /var/log/myservice.log < /tmp/myservice.pipe &
tee -a /var/log/myservice.err < /tmp/myservice.pipe.err &

# 3) myservice 실행 결과를 FIFO로 보냄 (stdout+stderr)
nohup myservice > /tmp/myservice.pipe 2> /tmp/myservice.pipe.err &

# 4) myservice 실행 결과를 확인
tail -f /var/log/myservice.log
tail -f /var/log/myservice.err

# 5) FIFO 파일 삭제
rm /tmp/myservice.pipe
rm /tmp/myservice.pipe.err

단일 컨슈머 다중 프로듀서 패턴을 구현하기 위해 하나의 파이프에 여러 개의 프로세스가 동시에 접근하는 방식으로 사용할 수도 있다. 여러 개의 센서로부터 데이터를 수집하여 수치를 기록하는 프로그램이 그 예시이다.


메세지 큐(Message Queue) 메세지 큐는 프로세스 간의 데이터를 큐에 저장하고, 다른 프로세스가 해당 큐에서 데이터를 읽어가는 방식이다. 이 방식은 비동기적으로 데이터를 전송할 수 있어, 프로세스 간의 통신을 효율적으로 처리할 수 있다.



스레드와 멀티 스레딩

스레드

스레드(Thread)는 프로세스의 실행 가능한 가장 작은 작업 단위로, 프로세스는 여러 개의 스레드를 가질 수 있다. 코드, 데이터, 스택, 힙 영역을 각각 생성하는 프로세스와 달리 스레드는 해당 영역의 자원을 공유한다.


멀티 스레딩

멀티 스레딩(Multi-threading)은 프로세스 내 작업을 여러 개의 스레드, 멀티 스레드로 나누어 동시에 실행하는 것을 의미한다. 이를 통해 프로세스의 작업을 병렬로 처리할 수 있으며, CPU 자원을 효율적으로 사용할 수 있다. 멀티 스레딩은 멀티 프로세싱과 유사하지만, 프로세스 간의 통신이 필요하지 않기 때문에 더 빠르게 작업을 수행할 수 있다. 하지만, 하나의 스레드에 문제가 발생하면 프로세스 전체가 영향을 받을 수 있다는 단점이 있다. 웹 브라우저의 렌더러 프로세스는 메인 스레드, 워커 스레드, 컴포지터 스레드, 레스터 스레드 등 여러 개의 스레드를 사용하여 웹 페이지를 렌더링한다.



공유 자원과 임계 영역

공유 자원(Shared Resource)

공유 자원은 시스템 안에서 각 프로세스, 스레드가 동시에 접근할 수 있는 자원을 의미한다. 모니터, 프린터, 메모리, 파일, 데이터 등의 자원이 공유 자원에 해당한다. 이 공유 자원을 여러 개의 프로세스나 스레드가 동시에 읽거나 쓰는 상황을 경쟁 상태(Race Condition)라고 한다. 경쟁 상태는 여러 프로세스나 스레드가 동시에 공유 자원에 접근하여 예상치 못한 결과를 초래할 수 있다.


임계 영역(Critical Section)

임계 영역은 공유 자원에 접근하는 코드의 부분을 의미한다. 이 영역에서는 동시에 여러 프로세스나 스레드가 접근하면 안 된다. 임계 영역에 접근하는 동안 다른 프로세스나 스레드가 해당 영역에 접근하지 못하도록 해야 한다. 이를 위해 동기화(synchronization) 기법을 사용하여 임계 영역에 대한 접근을 제어한다. 동기화 기법은 임계 영역에 대한 접근을 제어하여 경쟁 상태를 방지하고, 데이터의 일관성을 유지하는 데 사용된다. 동기화 기법에는 세마포어(Semaphore), 뮤텍스(Mutex), 모니터(Monitor) 등이 있다. 세 가지 방법 모두 상호 배제, 한정 대기, 융통성이란 조건을 만족하며 토대가 되는 매커니즘은 잠금(Lock)이다.

  • 상호 배제(Mutual Exclusion): 한 번에 하나의 프로세스나 스레드만 임계 영역에 접근할 수 있도록 하는 조건이다.
  • 한정 대기(Bounded Waiting): 임계 영역에 접근하기 위해 대기하는 프로세스나 스레드가 무한히 대기하지 않도록 하는 조건이다.
  • 융통성(Fairness): 임계 영역에 접근하기 위해 대기하는 프로세스나 스레드가 공정하게 접근할 수 있도록 하는 조건이다.

뮤텍스(Mutex) 뮤텍스는 상호 배제를 보장하는 동기화 기법으로, 한 번에 하나의 프로세스나 스레드만 임계 영역에 접근할 수 있도록 한다. 뮤텍스는 lock()unlock() 함수를 사용하여 임계 영역에 대한 접근을 제어한다. 뮤텍스는 프로세스나 스레드가 임계 영역에 접근하기 전에 잠금을 획득하고, 임계 영역을 벗어난 후 잠금을 해제한다.


세마포어(Semaphore) 세마포어는 공유 자원에 대한 접근을 제어하는 동기화 기법으로, 카운터를 사용하여 임계 영역에 접근할 수 있는 프로세스나 스레드의 수를 제한한다. 세마포어는 wait()signal() 함수를 사용하여 임계 영역에 대한 접근을 제어한다. 세마포어는 두 가지 유형이 있다.

  • 바이너리 세마포어(Binary Semaphore): 카운터가 0 또는 1인 세마포어로, 뮤텍스와 유사하게 동작한다. 한 번에 하나의 프로세스나 스레드만 임계 영역에 접근할 수 있다.
  • 카운팅 세마포어(Counting Semaphore): 카운터가 0 이상의 값을 가지는 세마포어로, 임계 영역에 접근할 수 있는 프로세스나 스레드의 수를 제한한다. 카운팅 세마포어는 여러 프로세스나 스레드가 동시에 임계 영역에 접근할 수 있도록 한다.

모니터(Monitor) 모니터는 동기화 기법 중 하나로, 공유 자원에 대한 접근을 제어하는 객체이다. 모니터는 내부적으로 뮤텍스와 조건 변수를 사용하여 임계 영역에 대한 접근을 제어한다. 모니터는 공유 자원에 안전하게 접근할 수 있도록 공유 자원을 캡슐화하고, 해당 접근에 대한 인터페이스를 제공하여 접근할 수 있도록 한다.



교착 상태

교착 상태(Deadlock)는 두 개 이상의 프로세스나 스레드가 서로의 자원을 기다리며 무한히 대기하는 상태를 의미한다. 교착 상태는 시스템의 자원을 효율적으로 사용하지 못하게 하고, 시스템의 성능을 저하시킬 수 있다.


교착 상태의 조건

교착 상태가 발생하기 위해서는 다음 네 가지 조건이 모두 충족되어야 한다.

  • 상호 배제(Mutual Exclusion): 자원은 한 번에 하나의 프로세스나 스레드만 사용할 수 있다.
  • 점유 대기(Hold and Wait): 프로세스나 스레드는 이미 할당된 자원을 점유한 상태에서 다른 자원을 요청할 수 있다.
  • 비선점(Non-preemption): 프로세스나 스레드는 이미 할당된 자원을 강제로 해제할 수 없다.
  • 순환 대기(Circular Wait): 프로세스나 스레드가 자원을 요청하는 순환 구조가 형성되어 있어, 서로의 자원을 기다리는 상태가 발생한다.

교착 상태의 해결 방법

교착 상태를 해결하기 위해서는 다음과 같은 방법을 사용할 수 있다.

  • 예방(Prevention): 교착 상태가 발생하지 않도록 시스템의 자원 할당 정책을 변경한다. 예를 들어, 점유 대기 조건을 제거하거나, 비선점 조건을 제거하는 방법이 있다.
  • 회피(Avoidance): 교착 상태가 발생하지 않도록 시스템의 자원 할당을 동적으로 조정한다. 예를 들어, 은행가 알고리즘(Banker's Algorithm)을 사용하여 자원을 할당할 때 교착 상태가 발생하지 않도록 한다.
  • 탐지(Detection): 교착 상태가 발생했는지 주기적으로 검사하고, 교착 상태가 발생한 경우 이를 해결한다. 예를 들어, 교착 상태 탐지 알고리즘을 사용하여 교착 상태를 탐지하고, 교착 상태에 빠진 프로세스를 종료하거나 자원을 강제로 해제하는 방법이 있다.
  • 회복(Recovery): 교착 상태는 매우 드물게 일어나기 때문에 이를 처리하는 비용이 더 크다. 따라서 현대 운영체제는 교착 상태가 발생하면 사용자가 이를 직접 해결하도록 하는 방식을 채택하고 있다.

Share this post

N