프로세스
- 실행 중인 프로그램
- 프로그램이 CPU에 의해 수행되고, 메모리에 할당된 상태
- 프로세스는 작업을 완료하기 위해 CPU, memory, file, I/O devices와 같은 자원을 필요로 한다.
- 각각의 프로세스는 독립된 메모리 영역을 할당 받는다.
* 프로그램 : 하드웨어를 동작시키는 명령어 집합
프로세스의 구조

프로세스는 메모리에서 위와 같이 여러개의 구역으로 나뉜다.
- 코드 영역(Text Section) : 실행 코드(명령어)가 저장됨
- 데이터 영역(Data Section) : 전역 변수, 정적 변수가 저장되는 영역
- 힙 영역(Heap Section) : 동적으로 할당된 메모리가 저장되는 영역
- 스택 영역(Stack Section) : 함수 호출 시 지역 변수, 매개변수, 리턴 주소 등이 저장되는 영역
* JVM으로 설명하면 코드 영역과 데이터 영역이 메서드 영역이다.
프로세스의 상태
상태 | 설명 |
new(생성) | 프로세스 생성 요청은 받았지만 아직 메모리 자원을 할당하지 않은 상태 |
ready(준비) | - 프로세스가 CPU에 수행될 수 있도록 메모리 할당과 초기화가 이루어진 상태 - ready queue에서 대기함 |
running(실행) | instruction(명령어)이 CPU에 의해 실행됨 |
waiting(대기) | - I/O completion, 시그널 수신과 같은 이벤트를 기다리는 상태 - waiting queue에서 대기함 - 대기(block) 상태라고 부름 |
terminate(종료) | 프로세스 종료 |

1. new -> ready
프로세스는 fork() 라는 시스템 콜을 통해 생성된다.
초기화를 진행하며 새로운 메모리 공간을 할당받고 각 영역에 메모리를 할당하는 등의 초기화가 끝나면 ready 상태에 도달한다.
2. ready -> running
ready 상태에 있는 프로세스는 ready queue에 위치한다.
CPU 자원을 할당 받으면 running 상태에 도달하는데 이 과정을 Dispatch라고 한다.
3. running -> ready
CPU는 time sharing한 방식으로 동작하기에 일정 시간이 지나면 다른 프로세스를 실행시켜야한다.
현재 실행 중인 프로세스는 CPU에 의해 interrupt되어 ready queue로 이동되고 다음 실행 기회를 기다린다.
4. running -> waiting
프로세스 실행 중 I/O 작업(또는 다른 block 이벤트)이 발생하면 현재 프로세스를 wait queue로 이동시킨다.
이때 ready queue로 이동시키지 않고 wait queue로 이동시키는 이유는 I/O 작업이 완료되지 않을 때까지 프로세스는 실행되면 안되기 때문이다. (blocking-sync)
5. waiting -> ready -> running
I/O 작업이 완료됬다는 신호를 받으면 wait queue에 있던 프로세스는 ready queue로 이동하고
ready queue에서 자신의 순서를 기다리다 CPU의 점유를 받게 되면 ruuning 상태에 도달하여 실행된다.
6. running -> terminate
실행이 종료되면 프로세스는 종료되며 메모리 영역에서 제거된다.
PCB(Process Control Block)
CPU가 프로세스를 변경시키며 수행하기 위해서 프로세스의 정보를 저장해야한다.
예를 들어 P0를 실행하다 P1을 실행하고 P0를 실행시킬 때 어디부터 실행해야하는지, 어떤 정보들을 레지스터에 저장했는지 등의 정보를 기억해야 시분할 작업을 진행할 수 있다.
이러한 정보를 저장시키는 공간이 PCB이다.
프로세스는 PCB로 나타내지며 아래와 같은 정보를 갖는다.

process state (프로세스 상태) |
new, ready, running, waiting, terminate와 같은 프로세스 상태 |
process number (PID) |
PID라는 process id 값으로 os에서 프로세스를 고유하게 식별하기 위한 값이다. |
program counter (PC) |
현재 실행 중인 코드 이후에 실행시킬 코드의 메모리 주소를 가리킨다. 프로세스가 interrupt 되어 ready queue에 이동된 다음 다시 running으로 될 때 이 값 부터 프로세스를 실행시킨다. |
CPU register | CPU의 레지스터 정보 CPU의 프로세스를 실행하기 위해 메모리에 매번 접근하는 것은 비효율적이기에 현재 실행하기 위해 필요한 정보들은 CPU의 레지스터에 저장시켜놓고 메모리가 아닌 CPU에 접근하여 실행한다. 이렇게 저장시켜 놓은 정보를 나중에 다시 실행하기 위해 PCB에 저장시켜 놓음 |
memory limit | 프로세스의 메모리 크기 |
memory management information |
- 프로세스 주소 - 프로세스의 각 메모리 영역 정보(크기, 주소 등) - 할당한 메모리와 사용 가능한 메모리 주소 |
I/O status infromation | - I/O 상태(진행, 완료, 오류 상태) - 프로세스가 사용 중인 I/O 장치(디스크, 프린터, 소켓 등) - 프로세스를 위해 열린 파일 목록 |
Context Switch
- context란 프로세스가 사용되고 있는 상태 정보인 PCB를 말하며 이를 교환하는 것을 Context Switch라고 한다.
- interrupt가 발생했을 때, 현재 실행 중인 프로세스의 context정보를 저장함
cpu 프로세서인 core는 한번에 하나의 작업만 가능하다. 동시에 여러 프로세스가 동작하도록 보이기 위해 매우 짧은 시간 단위로 프로세스를 번갈아가며 작업하기 위해 현재 실행 중인 프로세스를 interrupt하고 context switch를 하여 다른 프로세스를 실행시킨다.
Context Switch 과정
P0가 실행 중 interrupt가 발생하면 P0의 PCB를 저장한다.
그런 다음 P1을 실행시키기 위해 PCB1을 불러들이고 P1을 수행한다.
P1의 CPU 점유시간이 만료되어 현재 P1의 상태정보를 PCB1에 저장한다.
P0를 실행시키기 위해 PCB0를 다시 레지스터에 적재하고 P0를 수행한다.
PCB를 메모리에 저장하고 다시 레지스터 적재하는 과정이 context switch이다.
IPC(InterProcess Communication)
IPC란 프로세스간 통신을 의미한다.
프로세스 간에 데이터를 공유가 필요할 수 있다.
프로세스간 공유 데이터가 없다면 독립적인 프로세스라고 할 수 있지만,
공유 데이터가 필요하다면 프로세스간 통신이 필요하다.
프로세스간 통신에서 고려해야하는 메카니즘은
데이터를 어떻게 보낼것인지(send)와 데이터를 어떻게 받을 것인지(receive)이다.
IPC의 기본적인 모델에는 아래와 같은 모델이 존재한다.
- shared memory
- messaging passing
Shared Memory
shared memory 위와 같이 하나의 공유 메모리 공간을 두어 각 프로세스에서 데이터를 쓰거나 읽을 수 있도록 하는 것이다.
가장 단순한 방식은 버퍼 공간을 활용하는 것이다.
버퍼를 통해 읽고 쓰는 작업을 구현하는 것이다.
간단하게 예제를 통해 알아보자.
1. 부모 프로세스에서 버퍼 정의
2. Producer의 데이터 쓰기 작업 구현
3. Consumer의 데이터 읽기 작업 구현
위 예제는 부모 프로세스에서 shared memory 영역을 사용할 buffer 구조를 정의하고
buffer에 데이터가 가득 찼는지 확인하고 데이터를 쓰는 Producer를 구현하고
buffer에 데이터가 남아있는지 확인하고 읽어들이는 Consumer를 구현한 예제이다.
shared memory 방식은 응용 프로그램 개발자가 데이터를 읽고 쓰는 작업을 모두 개발해야하기에 복잡한 구현을 필요로 할 수 있다.
Messaging Passing
Messaging Passinig은 OS에서 send와 receive의 동작을 구현한 기능을 제공한다.
단순히 데이터를 send하거나 receive하는 것 이외에도 통신의 방식 또한 결정할 수 있다.
- direct, indirect
- blocking, non-blocking
direct 통신 방식은 sender와 receiver 프로세스간 직접적인 통신이다.
send(P, message), receive(Q, message)와 같이 수신 프로세스와 송신 프로세스를 명시하여 데이터를 공유하는 것이다.
indirect 통신 방식은 sender와 receiver 프로세스간 간접적인 통신으로 중간 매개체인 port를 활용한다.
send(port, message), receive(port, message)와 같이 중간 매개체 port에 데이터를 전송한다.
(port를 통해 통신할 수 있는 것은 OS 수준에서 지원하는 것이고, port에 매핑된 중간 매개체 역할을 하는 응용프로그램이 필요함)
blocking 방식은 통신이 수행되는 동안 다른 작업은 차단된다.
send와 receive가 끝날 떄까지 다른 작업은 수행하지 못한다.
non-blocking 방식은 통신이 수행되는 동안 다른 작업을 진행할 수 있다.
send와 receive가 이루어지는 동안 다른 작업은 수행할 수 있다.
Client-Server model
위에서 다룬 shared memory와 messaging passing 방식은 하나의 PC 내에서 프로세스간의 통신이 이루어지는 방법을 설명한 것이다.
이제는 네트워크를 통한 PC 간 통신이 많이 있기 때문에 shared memory나 messaging passing 방식 보다 socket을 통한 통신이 더욱 많이 이뤄지고 있다.
하나의 PC 내에서 이뤄지는 프로세스간 통신보다 네트워크를 통한 client-server 모델이 더욱 중요하기에 이에 대한 과정을 이해하는 것이 필요하다.
아래 글은 socket에 초점을 맞춘 내용은 아니지만 네트워크 통신의 방식을 다루고 있으니,
네트워크를 통한 PC간 통신을 이해하는데 어느정도 도움이 될 것이다.
- [I/O 이해하기-1] 동기와 비동기 VS Blocking과 Non Blocking
- [I/O 이해하기-2] Stream vs Channel
- [I/O 이해하기-3] 톰캣의 요청 수신 방식
'OS & Network > OS' 카테고리의 다른 글
동시성 문제[2] - Mutex, Semaphore, Monitor(동기화 도구) (0) | 2024.07.28 |
---|---|
동시성 문제[1] - 동시성 문제의 원인과 해결법 (0) | 2024.07.28 |
프로세스[2] - 멀티 프로세스와 멀티 스레드 (0) | 2024.07.25 |
메모리[2] - 페이징, 가상메모리 (0) | 2024.07.25 |
메모리[1] - 메모리 주소 할당 (0) | 2024.07.20 |