Reference
1. Abraham Silberschatz, Greg Gagne, Peter B. Galvin - Operating System Concepts (2018)
2. Operating System class by Professor Sukyong-Choi at Korea University
중요한 내용 위주로 요약 && 정리했습니다.
process는 실행 중인 program이다.
- 자원을 필요로 한다. (CPU time, memory, files, I/O devices
- unit of work
- System consist of a collection of processes
현대 OS는 “multiple threads”을 다루는 process를 지원한다.
- thread : process보다 작은 작업 단위
- thread가 병렬적으로 수행된다.
3.1 Process Concept
3.1.1 The Process
- 실행 중인 program
- process의 상태 정보는 (1) program counter (2) contents of the processor’s register로 구성
memory layout of a process
- Text section : the executable code
- Data section : global variables
- Heap section : 동적으로 할당된 memory
- Stack section : 함수가 호출될 때 사용되는 temporary data storage
- text, data 부분은 고정
- stack과 heap 부분은 동적. stack은 grow down, heap은 grow up // 겹치지 않도록 OS가 조절
Example
program ≠ process
- program : 디스크에 저장된 명령어 리스트를 포함하는 파일 (executable file)
- process : 다음 실행할 명령어를 나타내는 program counter와 관련 자원 집합을 가진다.
- 두 process가 동일 program가 관련되더라도 두 개의 독립된 실행 순서로 간주됨 ⇒ 이 경우 Text section은 동일하고 나머지는 다르다.
process는 또 다른 code의 execution environment가 될 수 있다.
- JVM
3.1.2 Process State
- new : process 생성
- ready : processor(CPU)에게 할당되기를 대기하는 상태
- running : Instructions이 실행 중
- waiting : 어떤 event가 일어나기를 기다리는 상태
- terminated : 실행 종료
processor core에서 실행될 수 있는 process는 오직 한 번에 한 개뿐
- 하지만 ready나 waiting 상태는 많은 process들이 존재할 수 있다.
3.1.3 Process Control Block (PCB)
process마다 각각 PCB를 가집니다.
PCB는 프로세스의 실행/재실행을 위해 필요한 모든 정보의 저장소 입니다.
또, PCB는 doubly linked list로 구현됩니다.
특정 process 관련 정보들을 포함
- process state : new, ready, running, waiting, halted 등
- program counter : 다음 명령어의 주소
- CPU registers : interrupt 발생 시 PC와 함께 상태 정보 저장 → reschedule 후 계속 실행됨
- CPU-scheduling information : process 우선순위, pointer, 다른 parameter 등
- Memory-management information
- Accounting information
- I/O status information
3.1.4 Threads
Single thread of execution
- process는 single thread를 실행하는 program
- single thread 제어는 한 번에 하나의 task만 실행함 → (ex) 문자 입력과 철자 검사를 동시에 x
Multiple thread
- process가 여러 실행 thread를 가지고 한 번에 하나 이상의 taks를 실행함
- Multi core system인 경우, 여러 thread가 병렬로 실행 가능
- Thread 지원 system에서 PCB가 각 thread에 대한 정보를 포함하도록 확장
3.2 Process Scheduling
Multiprogramming
- 항상 process들이 실행되도록 하여 CPU 이용률을 최대화함
Time sharing
- porcess 사이에서 CPU core를 자주 switch → user와 program이 상호 작용함
⇒ core에서 프로그램을 실행하기 위해 process scheduler가 실행 가능한 process를 하나 고름
single CPU core를 가진 system에서는 한 번에 한 process만 실행 가능하지만, multicore system에서는 multiple processes들이 동시에 실행될 수 있습니다.
이때, core의 수보다 process의 수가 더 많은 경우, process들이 wait해야 합니다.
Degree of multiprogramming
- 현재 메모리 내 process 수
Balancing the objectives of multiprogramming and time sharing
- multiprogramming과 time sharing의 균형을 위해서 적절하게 스케줄링 해야 한다.
- 시간 소비에 따라서 I/O bound or CPU bound process로 구분된다.
3.2.1 Scheduling Queues
- Process가 system에 진입 → Ready queue에 삽입, core에서 실행되기를 ready/wait 함
- Ready queue / Wait queue는 linked list 형태로 저장됨
- queue의 head는 첫 PCB의 포인터를 가짐; 각 PCB는 다음 PCB에 대한 포인터를 가짐
Queueing diagram
여기서 queue는 Ready or Wait queue 중 하나입니다.
종료 시점에 queue에서 제거되고 PCB와 자원이 해제됩니다.
3.2.2 CPU Scheduling
- process는 ready queue와 wait queue들 사이를 이주함
CPU Scheduler의 역할
- ready queue에서 하나의 process를 선택하고 CPU core를 할당함
- I/O bound process → 잠깐 실행 후 I/O 대기
- CPU bound process → 오랜 기간동안 CPU core가 필요해도 장기간 할당될 가능성은 없음 대신에 CPU를 뺏어서 다른 process에게 스케줄함
Swapping - 메모리 과부화 상태일 때 process 제거
- memory에서 process를 제거하여 다중화 정도를 낮추는 것
- 나중에 다시 memory로 적재되어 중단된 위치에서 계속 실행됨
- swapped out = 메모리 → 디스크
- swapped in = 디스크 → 메모리
- 메모리가 초과 사용되어 해제되어야 할 때만 필요하다
3.2.3 Context Switch
- interrupt 발생 시 OS는 현재 task로 부터 CPU core를 뺏아 kernel 루틴을 실행하게 함
- context : PCB에 저장된 process에 관련된 내용
interrupt 발생 시,,
- CPU core에서 실행 중인 process의 현재 context를 저장
- interrupt 처리가 끝나면 해당 context를 복원함
- 기본적으로 process를 일시 중단(suspending)하고 다시 실행(resume)함
Context Switch
- 다른 process에게로 CPU core를 switching하는 것
- PCB에 old process의 문맥을 저장; 실행될 new process의 saved 문맥을 load함
위 그림 상, “화살표” = running 상태 / “검은 선” = wait or ready 상태입니다.
Context-switch time
- pure overhead : 스위칭 동안 쓸모있는 일을 하지 않는다.
- 전형적으로 ms 속도이다
- 스위칭 속도는 메모리 속도, 복사돼야 하는 레지스터 수, 특수 명령어 등에 따라 다름
- 하드웨어 지원에 크게 좌우됨
3.3 Operations on Processes
processes들은 동시에 수행되고, 동적으로 생성/삭제 됩니다.
3.3.1 Process Creation
- 실행 중에 process는 새로운 process들을 생성한다.
- 생성한 process = parent process
- 생성된 process = children process
Process identifier (pid)
- pid로 process를 식별한다.
- kernerl 내에서 다양한 process의 속성에 접근하기 위한 index로 사용됨
command
- ps -el : 현재 실행중인 process들의 list를 보여줌
- pstree : tree로 보여줌
systemd process (pid=1)
- root parent process
- 모든 user process들의 부모이며, 부트 시 생성되는 첫 user process
- 부팅되면 systemd가 추가적인 서비스를 제공하는 process를 생성함
child process가 자원을 필요로 할 때
- 자식 process가 OS로 부터 직접 자원을 할당받거나
- 부모 process 자원의 부분집합으로 제한된다.
- 부모는 자식들 간에 자원을 분할하여 사용하거나, 자식들과 자원을 공유함
- 한 프로세스가 너무 많은 자식을 생성하여 시스템을 과부하 시키는 것을 막음
child process에 필요한 data 전달
ex) 파일 이름, 출력 장치 이름 필요
- OS가 자식 process에게 자원을 전달함
- 부모 process가 자식 process에게 초기화 data를 전달함
부모/자식 process의 실행
- 부모/자식 병렬 실행
- 부모가 자식이 종료될 때까지 기다림
부모/자식 process의 주소 공간 사용
- 자식이 부모의 복제본이면, 부모와 동일한 프로그램과 데이터를 가짐 [fork() system call]
- 자식 process가 자신에게 load되는 새로운 프로그램을 가짐
(1) UNIX OS에서의 process 생성
fork() system call : 새로운 process 생성하는 시스템 콜
- 새로운 process는 original 주소 공간의 복사본으로 구성됨
- 부모와 자식이 쉽게 통신하게 함
- pid = fork() : 리턴 = (1) 0 (자식) (2) child의 pid (부모)
After a fork() system call
- fork() 후, 한 process가 exec() system call 하여 메모리 공간을 새 프로그램으로 교체
- binary file을 memory로 적재[자신을 포함한 프로그램의 메모리 이미지를 파괴(덮어쓰기)]하고 실행함
- 자식을 더 생성하거나, 자식이 실행되는 동안 할 일이 없으면 자식이 종료될 때까지 ready queue에서 자신을 제거하기 위해 wait() system call을 함
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
pid t pid;
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) { /* child process */
execlp("/bin/ls","ls",NULL);
}
else { /* parent process */
/* parent will wait for the child to complete */
wait(NULL);
printf("Child Complete");
}
return 0;
}
자식 process
- 자식 process는 부모로부터 자원 뿐 아니라, 특권, 스케줄링 속성을 물려 받음
- exelip()를 이용하여 자신의 주소 공간을 ls 명령어로 덮어씀
부모 process
- wait() system call을 이용하여 자식 process가 끝날 때 까지 기다림
- 자식 process 종료 시, 부모는 wait() 호출로부터 재개함
(2) Windows OS에서의 process 생성
- window API인 CreateProcess()를 이용한다.
#include <stdio.h>
#include <windows.h>
int main(VOID)
{
STARTUPINFO si;
PROCESS INFORMATION pi;
/* allocate memory */
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
/* create child process */
if (!CreateProcess(NULL, /* use command line */
"C:∖∖WINDOWS∖∖system32∖∖mspaint.exe", /* command */
NULL, /* don’t inherit process handle */
NULL, /* don’t inherit thread handle */
FALSE, /* disable handle inheritance */
0, /* no creation flags */
NULL, /* use parent’s environment block */
NULL, /* use parent’s existing directory */
&si,
&pi))
{
fprintf(stderr, "Create Process Failed");
return -1;
}
/* parent will wait for the child to complete */
WaitForSingleObject(pi.hProcess, INFINITE);
printf("Child Complete");
/* close handles */
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
3.3.2 Process Termination
스스로 종료
- 마지막 문장을 실행하여 종료하고, exit() system call로 OS에 자신을 삭제 요청함
- wait() system call을 통해 대기중인 부모 process에 상태값이 반환됨
- process의 자원들은 OS에 의해 할당이 해제되고 회수됨
다른(부모) process에 의한 종료
- system call로 다른 process를 종료시킴 (TerminateProcess() in Window)
- 종료시키는 system call은 부모 process로 부터 호출됨
- process 종료를 위해서 부모는 자식의 pid를 알아야 함 ⇒ 이를 위해 process 생성 시 부모에게 pid가 전달됨
사용자에 의한 종료
- 사용자가 종료
부모가 자식 process를 종료시키는 이유
- 자식이 할당된 자원을 초과 사용한 경우
- 자식에게 할당된 task가 더 이상 필요하지 않은 경우; task 종료
- 부모가 exit 시, 자식이 계속 실행되는 것을 OS가 허용하지 않은 경우
Cascading termination
- 부모가 종료되면 자식이 존재할 수 없음 → 모든 자식이 종료되어야 함
- 자식이 종료될 때 pid가 return되어 부모는 어느 자식이 종료됐는지 식별 pid = wait(%status) // exit(1) → 1인 status로 종료
Process Table
- PCB의 array → 현재 존재하는 모든 process의 PCB
process의 exit status가 process table에 저장되므로 process table의 항목은 부모가 wait()를 호출할 때까지 남아있어야 합니다.
Zombile Process → 정상 종료 가능
- 종료되었거나, 부모가 아직 wait()를 호출하지 않은 process
- 부모가 wait()를 호출하면, 좀비 process의 pid와 process table의 항목이 해제됨
Orphan Process → 정상 종료 불가능
- 부모가 wait()를 호출하지 않고 종료한 경우 → PCB에 정보가 계속 남음
- System 선에서 정리해줘야 됨
- init process를 orphan process의 새로운 부모로 지정하여 해결한다.
- init이 주기적으로 wait()를 호출하여 orphan process의 exit status를 수집하고, orphan process의 id와 process table 항목을 해제함
- 대부분 Linux 시스템에서는 init이 systemd로 대체됨
3.4 Interprocess Communication (IPC)
process간 협력의 이유
- Information sharing
- Computation speedup
- Modularity
IPC Model
1. shared-memory model
- 공유 메모리 영역을 만들 때만 system call이 일어나므로 빠르다.
- 공유 메모리가 만들어지면 모든 접근이 일상적인 메모리 접근으로 취급되고, 커널의 도움 필요없음
- process들은 동시에 동일 위치에 쓰지 않도록 책임져야 함
2. message-passing model
- 작은 data를 교환할 때 유용하다
- 분산 system 환경에서 구현이 쉽다
- 느리다.
3.5 IPC in Shared-Memory Systems
- 공유 메모리 영역은 공유 메모리 segment를 생성하는 process의 주소 공간에 위치
- 공유 메모리 segment를 사용하여 통신하기를 원하는 process들은 자신의 주소 공간에 추가
- process들은 동시에 동일 위치에 쓰지 않도록 책임져야 함
Producer - Consumer Problem
- 한 쪽은 정보를 생산, 다른 쪽은 소비함
- Complier → assembly code 생산 , assembler → assembly code 소비
- client-server paradigm
⇒ shared memory 사용
- 동시에 실행하기 위해서는 producer는 버퍼를 채우고, consumer는 버퍼를 비워야 함
- Producer와 Consumer는 동기화 되어야 함 - 생산되지 않은 정보를 소비하지 않음
buffer
- unbounded buffer : consumer는 item 대기 가능, produver는 계속 생산 가능
- bounded buffer : consumer는 empty일 때 대기, producer는 full일 때 대기
⇒ bounded buffer를 사용한다. → 원형 배열로 구현
3.6 IPC in Message-Passing Systems
- 네트워크로 연결된 다른 컴퓨터들의 proceess간 통신
- send(message) receice(message)
- message의 길이는 고정이거나 가변이다.
- fixed-sized message : 시스템 수준 구현은 단순하나 task 프로그래밍이 어렵다
- variable-sized message : 시스템 수준 구현은 복잡하나 task 프로그래밍이 쉽다
- 통신을 원하면 message를 주고 받아야 함
3.6.1 Naming
- 통신을 원하는 process들은 서로 통신 상대를 지정해야 함
3.6.1.1 Direct communication (직접 연결 통신)
- recipient/sender process의 이름을 명시해야 함
- send(P, message) : process P에게 메시지 전달
- receive(Q, message) : process Q로부터 메시지 받음
- P와 Q가 직접적으로 연결된다.
1. Symmetry in addressing
- 통신하려면 둘 다 상대의 이름을 지정해야 함
2. asymmetry in addressing
- sender만 recipient를 naming
- send(P, message)
- receive(id, message) : any process로부터 받겠다. id는 통신이 있어난 process의 이름
단점
- process 정의에서 modularity가 제한된다.
- process id의 변경은 모든 다른 process 정의를 검사해서 변경해야 함
- id가 직접적으로 명시되는 hard-coding 기법이다.
3.6.1.2 Indirect communication - mailbox 이용
- mailbox는 process들이 메시지를 저장(send)하고 제거(receive)하는 객체
- 두 process가 공유 mailbox를 가질 때만 통신 가능
- 여러 mailbox를 통해 다른 process들과 통신
- send(A, message), receive(A, message) : mail box A를 통해서 통신
둘 이상의 process가 mailbox A를 공유하는 경우, 어떻게 해결해야 하나?
- link가 최대 두 process만 연관되도록 제한
- 최대 한 번에 한 process만 receive()
- 어떤 process가 메시지를 receive할 지 선택 (round robin)
mailbox 소유
1. process가 소유
- 소유자(수신자)와 사용자(송신자)로 구분함
- 각 mailbox마다 고유한 owner가 있음
- mailbox를 갖는 process가 종료되면 mailbox도 사라짐
- 사라진 mailbox에 메시지를 보내는 process는 mailbox가 없음을 통보 받음
2. OS가 소유
- 독립적으로 존재, 특정 process에 속하지 않음
- process가 mailbox를 생성/삭제하는 기능을 OS가 제공한다.
- mailbox를 생성하는 process가 owner이다.
- mailbox에 대한 권한은 system call로 다른 process에 전달 가능
3.6.2 Synchronization
- process간 통신은 send() / receive() 호출로 발생함
- blocking (synchronous) Send : 수신될 때까지 send 대기 → 수신 후 송신
- blocking (synchronous) Receive : 메시지가 avail할 때까지 receice 대기 → 송신 후 수신
- nonblocking (asynchronous) Send, Receive
⇒ send와 receive의 종류에 따라 4가지 조합이 가능
example - 둘 다 blocking인 경우
3.6.3 Buffering
- 메시지는 temporary queue에 보관
queue를 구현하는 세 가지 방법이 있다.
- Zero capacity : 보관 x
- Bounded capacity : n개 메시지 보관
- Unbounded capacity : 무한개 보관
'Computer Science > Operating System' 카테고리의 다른 글
[운영체제] 공룡책🦖 ch06. Synchronization Tools (0) | 2022.11.23 |
---|---|
[운영체제] 공룡책🦖 ch05. CPU Scheduling (0) | 2022.11.23 |
[운영체제] 공룡책🦖 ch04. Threads & Concurrency (0) | 2022.10.24 |
[운영체제] 공룡책🦖 ch02. Operating-System Structures (0) | 2022.10.08 |
[운영체제]공룡책🦖 ch01. Operating System Introduction (1) | 2022.09.28 |