운영체제 정리 - Process
프로세스 개념
프로세스란?
- 실행중인 프로그램(메모리에 로드된 excutable file)을 프로세스라고 한다.
- 프로세스의 상태는 PC(program counter)와 register로 나타난다
프로세스 구조
프로세스 메모리 구조
- 프로세스의 메모리 영역은 크게 4곳으로 분류된다
- Text 영역: excutable code 정보
- Data 영역: 전역 변수 정보
- Heap 영역: 동적 메모리
- Stack 영역: 함수 호출 시 임시 저장(파라미터,return 주소, 지역변수 등)
+ 하나의 프로그램은 여러개의 프로세스로 이루어진다. ex) chrom 탭, VScode 탭 등등
프로세스 상태
- 프로세스는 여러 상태를 가지며 유기적으로 변한다
new: 프로세스가 막 만들어짐
ready: 프로세서에게 할당되기를 기다림
running: 프로세서가 실행중임
waiting: 실행중이던 프로세스가 이벤트로 인해 중단됨
terminated: 작업을 마치고 종료됨
Process Control Block (PCB)
PCB 구조
- 운영체제에서 관리하는 각 프로세스의 정보를 가지고 있는 데이터 구조
- PID, State, PC, registere 값, 메모리 정보 등을 가지고 있다
프로세스 스케줄링
스케줄링 예시
- CPU utilization을 극대화하기 위해서는 멀티프로그래밍을 해야하고, 일의 순서를 관리해야한다
I/O-bound process
- cpu burst는 짧고 I/O 대기시간이 더 긴 프로세스
CPU-bound process
- cpu burst가 긴 연산이 많은 프로세스
Scheduling queues
Ready queue
- 메모리에 올라와있는 cpu할당을 기다리는 큐
Wait queues
- 특정 이벤트가 일어나야 메모리에 올라가는 대기중인 큐 ex) I/O wait queue, interrupt wait queue…
Context Switch
Context switch 과정
- cpu가 작업하는 프로세스가 바뀔 때, 이전의 프로세스 정보를 저장해야한다
- 이때 이전 프로세스의 정보를 PCB에 저장한다
- 이러한 과정이 Context Switch에서 일어나고 이는 오래걸리기 때문에, 최소화 하는것이 좋다
프로세스 명령어
프로세스 명령어 과정 예시
프로세스 생성
프로세스 생성에 관해서 부모가 자식프로세스를 생성하는 얘기만 나오길래 GPT에게 물어보니
처음 생성되는 프로세스를 제외하고 대부분의 모든 프로세스는 부모 프로세스에 의해 생성된다.
자원 공유 옵션
- 부모 프로세스와 자식 프로세스가 모든 자원을 공유하는 방법, 일부만 공유하는 방법, 공유하지 않는 3가지 옵션이 있다.
실행 옵션
- 병행하여 실행되거나(concurrently) 자식프로세스가 종료될 때까지 부모가 대기하는 2가지 옵션이 있다.
명령어
- fork(): 자신을 복제하여 새로운 프로세스를 만든다.
- exec(): fork()이후 사용하여 새로운 메모리를 가지도록 초기화한다.
프로세스 종료
- 프로세스는 마지막 구문 실행 후에 종료된다.
- 이때, wait()를 통하여 부모에게 return값을 전달하고
- 운영체제는 할당하였던 메모리를 회수한다.
명령어
- exit(): 정상적으로 프로세스를 종료시키는 명령어
- abort(): 비정상적인 상황에서 종료시킬 때 사용하는 명령어 ex) 메모리 침범
- kill(): PID(Process ID)를 지정하여 종료시킬 때 사용하는 명령어
- wait(): 부모가 자식의 종료를 기다릴 때 사용하는 명령어
좀비와 고아(orphan)프로세스
- zombie:부모가 wait를 호출하지 않아, 자식이 종료되었지만 PID 등 메타데이터가 남아있는 자식 프로세스
- orphan: 부모가 wait를 호출하지 않은채로 종료되어 자원을 가진채로 동작하지 않는 자식 프로세스
Interprocess Communication
- 프로세스는 독립적일 수도 있지만 서로 협력할 수도 있다.
- 이 때, 협력하는 프로세스끼리는 데이터를 공유해야한다.
- 프로세스끼리 협력하는 이유: 1. 자원 공유 2. 성능향상 3. 모듈화
Message passing과 Shared memory방법의 구조
프로세스끼리 자원 공유를 하는 방법에는 위와 같은 두가지 방법이 있다.
Shared Memory
- 프로세스가 같은 메모리를 공유하는 방법으로 운영체제의 개입이 적고, 프로세스간에 알아서 관리해야한다.
- 이때, 관리하는 방법이 동기화(Synchronization)에 관한 내용이다.
Producer-Consumer Problem
- 공유하는 버퍼의 크기가 제한이 없다면 unbounded-buffer 제한이 있다면 bounded-buffer이다.
- 대게는 bounded-buffer이고 생산자-소비자 문제도 이때를 가정한다
공유 변수 코드
- item 배열, 그리고 in, out의 int값을 공유한다
- Buffer size는 10이지만 full과 empty가 구분되기 위해서 buffer size -1 만큼만 채운다
생산자 프로세스 코드
- 생산자는 full이면 대기하고(하나만 비워진 것이 full) full이 아니면 cs(critical section)에 진입
- 버퍼에 값을 입력하고 in을 증가시킨다.
소비자 프로세스 코드
- 소비자는 empty이면 대기하고 empty가 아니면 cs(critical section)에 진입
- 버퍼에 있는 값을 가져오고 out을 증가시킨다.
Message-passaing
- 같은 메모리를 공유하지 않고 프로세스끼리 통신하는 방법
- 매 메세지 전달마다 운영체제의 도움이 필요하다.
- 두 프로세스 사이에 communication link를 만든다.
- send와 receive 명령어를 사용한다.
- Direct/Indirect, Syncronous/asynchronous 등으로 구현 방법이 나뉜다.
Direct Communication
send와 receive 명령에 대상을 명시한다. ex) send(P, message) - P에게 보낸다.
reveive(Q, message) - Q로부터 받는다.2개의 프로세스가 1개의 링크를 통해 자동으로 연결되고 주로 양방향 연결
Indirect Communication
- mailboxe(port라고도 함)를 통해 간접적으로 전달하는 방식
- send와 reveive 명령에 메일박스를 명시한다.
- 여러개의 프로세스가 메일박스의 여러 링크를 통해 전달하고 양방향, 단방향 연결 둘 다 가능
Synchronization
- blocking/non-blocking(synchronous/asynchronous) 방법이 있다.
- blocking send: 상대가 메세지를 받을 때 까지 대기
- blocking receive: 상대가 메세지를 보낼 때 까지 대기
- Non-blocking send: 메세지를 보내고 대기하지 않음
- Non-blocking receive: 메세지가 오면 받음
+ 만약 send, receive 둘 다 blocking이면 둘 다 대기하지 않고 어떤 지점에서 만나면 랑데부(rendezvous)라고 한다
buffering
- Zero capacity: 버퍼공간이 없어 바로 주고 받아야함 -> sender가 항상 대기( direct한 통신이 필요 - rendezvous 만약, direct하지 않으면 무한 대기 혹은 메세지가 버려질 수 있음)
- Bounded capacity: 한정된 버퍼공간이 있음 -> 버퍼공간 이상으로 보내야 하면 sender가 대기
- Unbounded capacity: 무한한 버퍼공간이 있음 -> sender가 대기하지 않음