프로세스에 관한 전반적인 내용을 다뤄보자.
1. Process
프로세스(process)란 실행 중인 프로그램을 뜻하며, 잡(job)이라고도 한다.
프로세스는 CPU를 획득해 코드를 수행하기도 하고, 때로는 CPU를 반환하고 I/O 작업을 수행하기도 한다.
구분 | 동작 |
---|---|
프로그램 | 디스크에 실행파일 형태로 존재 |
프로세스 | 메모리에 올라가서 실행 |
프로세스 주소 공간 (Process Address Space)
코드(code, text):
프로그램 함수들의 코드가 CPU에서 수행할 수 있는 기계어 명령 형태로 컴파일되어 저장되는 부분
데이터(data):
전역 변수(global variable), 정적 변수(static variable) 등 프로그램이 실행되기 전 초기화 되는 데이터를 저장하는 부분
스택(stack):
지역 변수(local variable), 함수 인자(parameter), 리턴 주소(return address) 등을 임시로 저장하는 부분
힙(heap):
동적 메모리 할당(dynamic memory allocation)에 사용되는 메모리 영역 (데이터와 스택 사이의 빈 부분)
스택과 힙은 서로 반대 위치에서 마주보며 그 크기가 커지므로, 그 둘이 만나게 되면 stack overflow가 발생한다.
운영체제가 프로그램을 프로세스로 바꾸는 과정
프로그램 실행 파일에 존재하는 코드(code)와 데이터(static data)를 메모리의 프로세스 주소 공간에 탑재(load)한다.
페이징(paging), 스와핑(swapping) 등의 동작을 통해, 프로그램을 실행하면서 코드나 데이터가 필요할 때 필요한 부분만 메모리에 적재한다.
일정량의 메모리를 프로그램의 스택(stack, run-time stack)으로 할당한다.
스택은 지역 변수, 함수 인자, 리턴 주소 등을 저장하기 위해 사용된다.
프로그램의 힙(heap)을 위한 메모리 영역을 할당한다.
힙은 동적으로 할당되는 메모리로 연결 리스트, 해시 테이블, 트리 등 크기가 가변적인 자료구조를 위해 사용된다. 메모리를 요청하는
malloc()
및 메모리를 반환하는free()
와 관련이 있다.입출력과 관련된 초기화 작업을 수행한다.
Unix의 경우, 각 프로세스는 기본적으로 표준 입력(
STDIN
), 표준 출력(STDOUT
), 표준 에러(STDERR
) 장치에 해당하는 세 개의 파일 디스크립터(file descriptor)를 가지게 된다.운영체제는 생성된 프로세스에게 CPU를 넘긴다.
CPU 가상화
운영체제는 CPU를 가상화하여 하나 또는 소수의 CPU로 여러 개의 가상 CPU가 존재하는 듯한 환상을 만들어 내어 여러 프로그램을 동시에 실행하는 것처럼 보이게 하는데, 이를 시분할(time sharing) 기법이라 한다.
이러한 시분할 환경에서는 타이머 인터럽트(timer interrupt)를 통해 여러 프로세스를 짧은 시간 간격으로 번갈아 가며 수행한다.
따라서 프로세스가 CPU를 다시 획득해 실행을 재개하려면 직전 수행 시점의 상태를 재현해야 하며, 이때 필요한 정보가 프로세스의 문맥(context)이다.
프로세스의 문맥 (Context)
구성 요소 | 설명 | 예시 |
---|---|---|
하드웨어 문맥 | CPU의 수행 상태 | 프로그램 카운터(program counter) 등 각종 레지스터 값 |
프로세스 주소 공간 | 프로세스의 독자적인 주소 공간 | 코드, 데이터, 스택 |
커널 상의 문맥 | 운영체제는 프로세스를 관리하기 위한 자료구조를 유지 | PCB, 커널 스택(kernel stack) |
2. Process State
- 시작 상태 (
new
)- 프로세스가 시작되어 그 프로세스를 위한 각종 자료구조는 생성되었으나, 아직 메모리 획득을 승인 받지 못한 상태이다.
- 준비 상태 (
ready
)- 프로세스가 CPU만 보유하면 당장 명령을 실행할 수 있지만, CPU를 할당 받지 못한 상태이다.
- 메모리 적재가 된 상태이다.
- 실행 상태 (
running
)- 프로세스가 CPU를 보유하고, 기계어 명령을 실행하고 있는 상태이다.
- CPU가 하나인 일반적인 컴퓨터 시스템에서는 여러 프로세스가 동시에 수행된다고 해도, 실제로 실행 상태에 있는 프로세스는 매 시점 하나 뿐이다.
- 봉쇄 상태 (
blocked
,wait
,sleep
)- CPU를 할당 받더라도 당장 명령을 실행할 수 없는 상태이다.
- ex) 프로세스가 요청한 I/O 작업이 진행 중인 경우
- 완료 상태 (
terminated
)- 프로세스가 종료되었으나 운영체제가 그 프로세스와 관련된 자료구조를 완전히 정리하지 못한 상태이다.
3. Process Control Block (PCB)
운영체제가 시스템 내의 프로세스들을 관리하기 위해 프로세스마다 유지하는 정보를 담는 자료구조로, 커널의 데이터 영역에 위치한다.
PCB는 다음의 요소로 구성된다.
구성 요소 | 설명 |
---|---|
process state | CPU를 할당해도 되는지 여부를 결정하기 위해 필요 |
program counter 값 | 다음에 수행할 명령의 위치를 가리키는 값 |
CPU register 값 | CPU 연산을 위해 현 시점에 레지스터에 저장된 값 |
CPU scheduling 정보 | 해당 프로세스의 CPU 스케줄링을 위해 필요한 정보 |
메모리 관리 정보 | 해당 프로세스의 메모리 할당을 위해 필요한 정보 |
자원 사용 정보 | 사용자에게 자원 사용 요금을 계산해 청구하는 등의 용도 |
I/O status 정보 | 프로세스가 오픈한 파일 정보 등 |
CPU를 가상화하기 위해서는 문맥 교환(context switch)과 스케줄링 정책(scheduling policy)이 필요하다.
4. Context Switch
문맥 교환(context switch)이란 하나의 사용자 프로세스로부터 다른 사용자 프로세스로 CPU의 제어권이 이양될 때, 원래 수행 중이던 프로세스의 문맥을 저장하고 새로운 프로세스의 문맥을 설정하는 과정이다.
다음과 같은 경우에 문맥 교환이 발생한다.
- 타이머 인터럽트(timer interrupt)가 발생할 때
running
상태에 있던 프로세스가 I/O 요청 혹은 다른 조건을 충족하지 못하여blocked
상태로 바뀔 때
(예시1) 프로세스 A가 running
상태에서 실행되는 중에 타이머 인터럽트가 발생한 경우
- CPU의 제어권이 운영체제로 이양된다.
- 운영체제는 timer interrupt service routine으로 가서 수행 중이던 프로세스의 문맥을 저장하고,
ready
상태에 있는 프로세스 중 새롭게 CPU의 제어권을 부여할 프로세스 B를 선택한다. - 프로세스 A는
ready
상태로 변하고, 새롭게 CPU를 할당받은 프로세스 B가running
상태가 된다.
프로세스 | 동작 |
---|---|
원래 CPU를 보유하고 있던 프로세스 A | PC 값 등 프로세스의 문맥을 자신의 PCB에 저장한다. |
새롭게 CPU를 할당 받을 프로세스 B | 예전에 저장했던 자신의 문맥을 PCB로부터 실제 하드웨어로 복원한다. |
(예시2) 프로세스 A가 I/O를 요청한 경우
running
상태에 있는 프로세스 A가 I/O를 요청한다.프로세스 A는 I/O 작업이 완료될 때까지 CPU를 반환한 다음, 디스크 I/O 서비스를 기다리며
blocked
상태로 바뀐다.디스크에서 읽는 작업은 CPU 처리 속도에 비해 상대적으로 긴 시간이 소요되는 작업이기 때문이다.
- CPU 스케줄러가 CPU를 기다리는
ready
상태의 프로세스 중 적절한 프로세스 B를 선정하여 CPU를 할당한다. - CPU를 할당 받은 프로세스 B는
running
상태로 변경되어 자신의 코드를 CPU에서 실행한다. - I/O를 요청한 프로세스 A는 디스크 I/O를 기다리는 queue에 줄을 서있다가, 자기 차례가 되어 디스크 컨트롤러로부터 서비스(디스크 → 로컬버퍼)를 받는다.
- I/O 작업이 완료되면 디스크 컨트롤러가 CPU에 인터럽트를 발생시켜 작업 완료 사실을 알린다.
CPU는 다른 프로세스(B라고 가정)를 실행하고 있다가 인터럽트가 발생한 것을 확인하고, 인터럽트 처리루틴을 수행한다.
이때, 프로세스 B는 user mode
running
상태에서 kernel moderunning
상태로 바뀐다.- 인터럽트 처리루틴은 직전에 실행 중이던 프로세스 B와 무관한 업무를 담고 있기는 하나, 편의상 인터럽트 처리는 직전 프로세스(B)의 문맥에서 실행된 것으로 간주한다.
- 즉, 인터럽트를 당한 프로세스 B가 kernel mode로 진입한 것으로 간주한다.
인터럽트 처리루틴의 동작은 다음과 같다.
- I/O가 완료된 프로세스 A의 상태를
blocked
상태 →ready
상태로 바꾼다. - 장치의 로컬버퍼에 있는 내용을 메모리로 이동시킨다.
- I/O가 완료된 프로세스 A의 상태를
인터럽트 처리가 끝나면 인터럽트 처리루틴 이전에 수행되던 프로세스 B에게 CPU를 다시 할당하여, 해당 프로세스의 직전 수행 시점 이후의 코드를 실행한다.
이때, 스케줄링 방법에 따라 입출력이 완료된 프로세스 A가 우선순위가 더 높은 프로세스라면 문맥 교환(context switch)을 통해 CPU 제어권을 이양시킬 수도 있다.
문맥 교환이 발생하지 않는 상황
어떤 프로세스가
running
상태일 때, 일반적인 system call이나 interrupt가 발생하는 경우에도 문맥 교환이 일어날까?
일반적인 system call이나 interrupt가 발생하는 상황에서는 실행 중인 프로세스의 실행을 잠시 멈추고, 해당 프로세스의 실행 모드만이 user mode에서 kernel mode로 바뀌어 운영체제 커널의 코드를 실행하게 된다.
이러한 경우에도 CPU의 실행 위치와 같은 프로세스 문맥 중 일부를 PCB에 저장하긴 하지만, 이는 CPU를 점유하는 프로세스가 다른 프로세스로 변경되는 과정이 아니므로 문맥 교환이라고 하지 않는다.
이처럼 단순히 프로세스의 실행 모드만 변경하는 오버헤드는 문맥 교환에서의 오버헤드보다 훨씬 작다.
문맥 교환이 발생하는 상황과 발생하지 않는 상황을 표로 정리하면 다음과 같다.
문맥 교환 | 상황 | 설명 |
---|---|---|
O | (1) timer interrupt 발생 (2) 프로세스가 I/O 요청 system call을 통해 blocked 상태 진입 | 다른 프로세스가 CPU를 점유하게 되기 때문이다. |
X | 그 밖의 interrupt 혹은 system call 발생 | 하나의 프로세스의 실행 모드만이 user mode에서 kernel mode로 바뀌어 interrupt 처리를 하고, 다시 동일한 프로세스의 user mode로 돌아와 이전에 수행하던 작업을 계속 수행하는 것이기 때문이다. |
5. Process Scheduling
프로세스를 스케줄링하기 위한 큐
운영체제는 각 프로세스의 상태(ex. CPU를 기다리는지, I/O를 기다리는지 등)를 관리하기 위해 다양한 큐(queue)를 이용한다.
이러한 큐는 커널의 데이터 영역에 위치하고, 각 프로세스의 PCB가 연결 리스트 형태로 연결되어 있어 포인터를 사용해 순서를 정하게 된다.
프로세스를 스케줄링하기 위한 큐의 종류는 다음과 같다.
- 하드웨어 자원을 기다리는 큐
- 준비 큐 (ready queue)
ready
상태에 있는 프로세스들을 줄 세우기 위해 가지고 있는 큐이다.- 제일 앞의 프로세스에게 제일 먼저 CPU를 할당하며, 줄을 세우는 방법은 CPU 스케줄링 방법에 따라 달라진다.
- 장치 큐 (device queue)
- 특정 자원을 기다리는(즉,
blocked
상태인) 프로세스들을 줄 세우기 위해 장치별로 가지고 있는 큐이다. ex) 디스크 입출력 큐, 키보드 입출력 큐 등
프로세스가 디스크에 I/O 서비스를 요청한 경우,
- 해당 프로세스는 디스크 입출력 큐에 줄을 선다.
- 디스크 컨트롤러는 디스크 입출력 큐에 줄 서있는 순서대로 프로세스들의 I/O 작업을 수행한다.
- 프로세스의 I/O 작업이 완료되면 디스크 컨트롤러가 CPU에게 interrupt를 발생시킨다.
- interrupt service routine에 의해 I/O 작업이 완료된 해당 프로세스는 (1) 디스크 입출력 큐에서 빠져나와 (2) CPU를 기다리는 준비 큐에 줄을 선다.
- 특정 자원을 기다리는(즉,
- 준비 큐 (ready queue)
- 소프트웨어 자원을 기다리는 큐
- 자원 큐 (resource queue)
- 데이터 일관성을 위해 공유 데이터에 먼저 접근 중인 프로세스가 해당 데이터를 다 사용하고 반납할 때까지 다른 프로세스는 공유 데이터에 접근하면 안 된다.
- 데이터에 접근 중인 프로세스가
ready
상태나blocked
상태로 변경 되어 현재 CPU가 그 데이터를 사용하고 있지는 않더라도, 새롭게 CPU를 할당 받은 프로세스가 동일한 데이터에 접근하게 되면 데이터의 일관성이 깨질 수 있으므로 접근을 허용해서는 안 된다. - 여러 프로세스가 공유 데이터에 동시에 접근하려 하는 경우, 공유 데이터를 기다리는 자원 큐에 줄을 세우고, 공유 데이터가 반납되면 순서대로 데이터의 접근 권한을 부여한다.
- 자원 큐 (resource queue)
이때, 프로세스의 상태와 무관하게 현재 시스템 내에 있는 모든 프로세스가 속하는 큐를 작업 큐(job queue)라고 한다. 즉, 준비 큐와 장치 큐에 속하는 프로세스들은 모두 작업 큐에 속한다고 볼 수 있다.
따라서 작업 큐에 존재하는 프로세스라고 해서 반드시 메모리를 가지고 있는 것은 아니다. 준비 큐에 속한 프로세스는 ready
상태에, 장치 큐에 속한 프로세스는 blocked
상태에 있으며, 프로세스는 상태 변화에 따라 준비 큐 ↔ 장치 큐를 오가며 실행된다.
스케줄러의 종류
스케줄러(scheduler)란, 어떤 프로세스에게 자원을 할당할지를 결정하는 운영체제 커널의 코드를 말한다.
- 장기 스케줄러 (long term scheduler) / 작업 스케줄러 (job scheduler)
어떤 프로세스를 준비 큐에 진입시킬지 결정, 즉, 프로세스에게 메모리를 할당하는 문제에 관여한다.
준비 큐(
ready
상태) = CPU만 얻으면 당장 실행될 수 있는 상태로, 메모리에 적재된 상태new
상태의 프로세스 중 어떠한 프로세스를 준비 큐(ready
상태)에 삽입, 즉 메모리를 할당할 것인지 결정한다.- 메모리에 동시에 올라가 있는 프로세스의 수(= degree of multiprogramming)를 조절한다.
- 현대의 시분할 시스템에서 사용되는 운영체제에는 일반적으로 장기 스케줄러가 없으며, 프로세스가
new
상태가 되면 곧바로 프로세스에 메모리를 할당하여 준비 큐에 넣어준다.
- 단기 스케줄러 (short term scheduler) / CPU 스케줄러
ready
상태의 프로세스 중 어떠한 프로세스를 다음 번에running
상태로 만들 것인지 결정한다.- 준비 큐에 있는 여러 프로세스들 중 어떠한 프로세스에게 CPU를 할당할 것인가를 결정한다.
- timer interrupt가 발생하면 단기 스케줄러가 호출된다.
- 중기 스케줄러 (medium term scheduler)
- 너무 많은 프로세스에게 메모리를 할당해 시스템의 성능이 저하되는 경우를 해결하기 위해 메모리에 적재된(= 준비 큐에 존재하는) 프로세스의 수를 동적으로 조절한다.
- 너무 많은 프로세스가 메모리에 적재되면 프로세스당 보유 메모리양이 극도로 적어지게 되어, 디스크 입출력이 수시로 발생하여 시스템 성능이 심각하게 저하될 수 있다.
프로세스당 보유 메모리양이 지나치게 적어진 경우, 메모리에 올라와 있는 프로세스 중 일부를 선정하여 메모리를 수거해 그 내용을 디스크의 swap area에 저장(= swap out)한다.
swap out 우선순위
blocked
상태의 프로세스: 당장 CPU를 획득할 가능성이 없기 때문이다.- timer interrupt가 발생해 준비 큐로 이동하는 프로세스: 다시 CPU를 할당받기까지 오랜 시간이 소요될 것이기 때문이다.
- 장기 스케줄러와 마찬가지로 메모리에 동시에 올라가 있는 프로세스의 수(= degree of multiprogramming)를 조절한다.
중기 스케줄러가 있는 경우의 프로세스 상태
중기 스케줄러에 의해 메모리를 보유하지 않고 디스크로 swap out 된 프로세스의 상태는 suspended
상태로 나타낼 수 있다.
suspended
상태란 외부적 이유로 프로세스 수행이 정지된 상태로, 외부에서 재개시키지 않는 이상 다시 활성화될 수 없으며 다음의 두 가지 상태로 나타날 수 있다.
suspended blocked
상태blocked
상태의 프로세스가 중기 스케줄러에 의해 디스크로 swap out 된 경우
suspended ready
상태ready
상태의 프로세스가 중기 스케줄러에 의해 디스크로 swap out 된 경우suspended blocked
상태의 프로세스가 blocked 되었던 조건을 만족하게 된 경우
6. Process Operations
부모 프로세스와 자식 프로세스
시스템 부팅 후 최초의 프로세스는 운영체제에 의해 생성되지만, 그 후 생성되는 프로세스는 이미 존재하는 프로세스에 의해 복제 생성된다. 즉, 부모 프로세스가 자식 프로세스를 생성한다.
- 부모 프로세스와 자식 프로세스는 별도의 주소 공간을 갖는다.
- 처음 자식 프로세스의 주소 공간을 생성할 때에는 부모 프로세스의 주소 공간 내용을 그대로 복사한다. (
fork()
) - 자식 프로세스가 생성된 후, 다른 프로그램을 수행하기 위해서는 새로운 프로그램의 주소 공간을 덮어씌워 실행한다. (
exec()
)
따라서 프로세스는 계층 관계를 형성하며, 자식 프로세스가 먼저 죽고 이에 대한 처리는 부모 프로세스가 담당하게 된다. 즉, 어떠한 프로세스는 자신이 생성한 모든 후손 프로세스를 연쇄적으로 종료시킨 후에야 종료될 수 있다.
이때, 프로세스가 수행되는 모델은 다음의 두 종류가 있다.
- 부모와 자식이 공존하며 수행되는 모델: 부모와 자식이 CPU를 획득하기 위해 경쟁하는 관계가 된다.
- 자식이 terminate 될 때까지 부모가
wait()
하는 모델: 자식 프로세스가 종료될 때까지 부모 프로세스는 아무 일도 하지 않고blocked
상태에 머물러 있다가, 자식 프로세스가 종료되면ready
상태가 된다.
자식 프로세스를 생성하는 과정
fork()
시스템 콜
- CPU의 제어권이 커널로 넘어가고, 커널은
fork()
를 호출한 프로세스를 복제(= 자신과 똑같은 프로세스를 생성)하여 자식 프로세스를 생성한다. 생성된 자식 프로세스는 프로세스 ID를 제외한 모든 정보(주소 공간, 프로그램 카운터, 레지스터 상태, PCB, 커널 스택 등 모든 문맥)을 부모 프로세스와 동일하게 가지고 있다.
따라서 자식 프로세스는 부모 프로세스가 현재 수행한 시점(= PC 지점)부터 수행하게 된다.
- 부모 프로세스와 자식 프로세스는 주소 공간을 따로 갖게 되나, 주소 공간 내에는 동일한 내용을 가지게 된다.
fork()
함수의 반환 값으로 자신이 원본 프로세스인지 복제본인지 판단할 수 있다. 따라서 조건문을 사용해 원본 프로세스와 복제본 프로세스가 다른 작업을 하도록 프로그램을 작성할 수 있다.프로세스 종류 fork() 반환 값 원본 프로세스 (부모) > 0 복제본 프로세스 (자식) == 0 - Unix의
fork()
는 copy-on-write 기법을 이용하여 프로세스를 복사하는 작업을 부모나 자식이 page에 write 작업을 하기 전까지 지연시킨다. 이를 통해 필요한 page 만을 복사하여 전체가 복사되는 현상을 방지한다.
fork()
시스템 콜을 통해 자식 프로세스를 생성하면, 조건문에 의한 분기로 다른 동작을 수행할 수는 있으나 부모 프로세스와 동일한 코드를 가질 수밖에 없다.
exec()
시스템 콜
- 복제된 자식 프로세스에서 부모와는 다른 독자적인 프로그램을 수행시킬 수 있도록 하는, 즉, 프로세스의 주소 공간에 새로운 프로그램을 덮어씌우는 동작을 제공한다.
- 프로세스의 주소 공간을 완전히 새로운 프로그램으로 덮어씌운 후, 새로운 프로그램의 첫 부분부터 다시 실행을 시작하도록 한다.
wait()
시스템 콜
fork()
후에 호출하면 부모 프로세스는 자식 프로세스가 종료될 때까지blocked
상태에 머무르게 되고, 자식 프로세스가 종료되면ready
상태(준비 큐 진입)로 변경된다.- 부모 프로세스와 자식 프로세스 간의 동기화(synchronization)을 가능하게 한다.
프로세스 종료의 두 가지 타입
부모 프로세스가 종료되기 전, 모든 자식 프로세스들이 먼저 종료되어야 한다.
- 프로세스가 마지막 명령을 수행한 후, 이를 운영체제에게 알려 이루어지는 자발적 종료
exit()
시스템 콜을 통해 프로세스가 운영체제에게 자신이 종료됨을 알린다.- 종료를 통보 받은 운영체제는 프로세스로부터 자원을 회수하고 프로세스를 정리한다.
exit()
함수는 컴파일러가 자동으로 프로그램이 종료되는 지점에 삽입한다.
- 부모 프로세스가 자식 프로세스의 수행을 강제로 종료시키는 비자발적 종료
abort()
함수를 통해 이루어진다.- 강제 종료가 발생하는 경우
- 프로세스가 할당 자원의 한계치를 넘어서는 많은 양의 자원을 요구하는 경우
- 자식 프로세스에게 할당된 작업이 더 이상 필요하지 않은 경우
- 부모 프로세스가 종료(
exit
)되는 경우 (→ 단계적 종료)
종료되는 프로세스의 자식 프로세스를 계속 실행시키려면 종료되지 않을 다른 프로세스의 양자로 자식 프로세스를 보내야 한다.
ex) 로그아웃 후에도 특정 프로그램을 계속 수행해야 하는 경우, 해당 프로세스를 로그아웃 후에도 존재하는 시스템 프로세스의 자식으로 이양시키는 절차가 필요하다.
프로세스와 관련된 시스템 콜 정리
특권 명령에 해당하므로 시스템 콜을 통해서만 수행이 가능하다.
fork()
시스템 콜: 프로세스 ID를 제외한 모든 정보를 부모 프로세스와 동일하게 가지고 있는 자식 프로세스를 생성한다.exec()
시스템 콜: 자식 프로세스의 주소 공간에 새로운 프로그램을 덮어씌운다.exit()
시스템 콜: 프로세스가 운영체제에게 자신이 종료됨을 알린다. (자발적 종료)wait()
시스템 콜: 부모 프로세스를 자식 프로세스가 종료될 때까지 sleep(blocked
상태)시키고, 자식 프로세스가 종료되면 부모 프로세스를 깨워ready
상태(준비 큐 진입)로 변경한다.
7. Inter-Process Communication (IPC)
프로세스는 각자 자신만의 독립적인 주소 공간을 가지므로 다른 프로세스의 주소 공간을 참조할 수 없기 때문에 프로세스 간의 협력을 위해서는 여러 메커니즘이 필요하다.
이때, 하나의 컴퓨터 안에서 실행 중인 서로 다른 프로세스 간 발생하는 통신을 IPC라고 하며, 이는 통신(communication)과 동기화(synchronization)를 보장해주어야 한다.
IPC는 프로세스 사이에 공유 데이터를 사용하는지 여부에 따라 크게 두 가지로 나뉜다.
메시지 전달 방식 (Message Passing)
- 공유 데이터를 사용하지 않고 메시지를 주고 받으며 통신한다.
send(message)
와receive(message)
라는 두 가지 연산을 통해 메시지를 주고 받는 동작(특권 명령)을 운영체제에게 시스템 콜 방식으로 요청한다.- 통신을 원하는 두 프로세스는 커뮤니케이션 링크(communication link)를 생성하여 메시지를 주고 받는다.
직접 통신 vs. 간접 통신
통신 방법 특징 직접 통신 - 통신하려는 프로세스의 이름을 명시적으로 표시
- 링크는 자동으로 생성되고, 하나의 링크는 한 쌍의 프로세스에 할당됨
- 각 쌍의 프로세스에는 오직 하나의 링크만이 존재함
- 링크는 단방향성일 수 있으나, 대부분 양방향성간접 통신 - 메시지를 mail box 또는 port로부터 전달받음
- 각 mail box에는 고유 ID가 있으며, 이를 공유하는 프로세스들만 서로 통신 가능
- 링크는 프로세스 간 mail box를 공유하는 경우에만 생성됨
- 하나의 링크가 여러 프로세스들에게 할당될 수 있음
- 각 쌍의 프로세스는 여러 링크를 공유할 수 있음
- 링크는 단방향성 또는 양방향성
- 메시지를 보내는/받는 프로세스를 지정하는 방법도 존재
공유 메모리 방식 (Shared Memory)
- 프로세스들이 주소 공간의 일부를 공유한다.
- 운영체제에서 공유 메모리를 사용하는 시스템 콜을 지원하여, 서로 다른 프로세스들이 그들의 주소 공간 중 일부를 공유할 수 있도록 한다.
- 두 프로세스는 독자적인 주소 공간을 가지고 있으나, 이 주소 공간이 물리적 메모리에 매핑될 때 공유 메모리 주소 영역에 대해서는 동일한 물리적 메모리 주소로 매핑되는 것이다.
- 프로세스들이 직접 공유 메모리 접근에 대한 동기화 문제를 해결해야 한다.
References
- “운영체제와 정보기술의 원리(반효경 저)”, 5장 프로세스 관리
- “Operating Systems: Three Easy Pieces” (https://pages.cs.wisc.edu/~remzi/OSTEP/)
- https://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/3_Processes.html