프로세스
프로세스
프로그램 vs 프로세스의 차이
- 프로그램
실행이 가능한 형태인 바이너리 코드로 보조기억장치에 저장되어 있는 형태
- 프로세스
- 프로그램들을 load하여 주기억장치로 가져온 상태
- 스케줄러가 선정해서 실행프로세스마다 process ID(PID)를 중복되지 않게 부여해서 구분
프로세스의 정의
- 프로그램을 load하여 주기억장치로 가져온 상태
- 프로그래밍 언어처럼 위에서 아래로 내려오는 flow를 묶어서 덩어리화
- 변수값을 넣으면 결과가 바뀌듯이 동적인 상태
- 스케줄러가 선정해서 실행
- PID를 부여하여 구분
프로세스의 메모리 할당
프로세스의 구조

- code segment: 프로세스의 소스코드를 저장하는 공간
- static data: 상수나 전역변수 등 특수 목적의 변수를 저장
- heap: new, malloc으로 동적할당된 변수들을 저장
- stack: 프로세스에서 생성되는 일반 변수들을 저장
프로세스를 실행하며 변수가 생성되고 사라지고를 반복하는데 이 변수들은 heap과 stack영역 안에서 push되고 pop됨.
stack과 heap은 서로 머리를 마주보고 커짐
프로세스 상태
- new: 프로세스를 메모리에 올린 상태
- ready: 프로세스가 실행되기 전 준비하는 상태
- running: 프로세스가 실행되는 상태 / 반드시 ready상태에서만 올 수 있음
- waiting: I/O 요청으로 인해 I/O 결과를 대기하는 상태
- terminated: 프로세스가 메모리에서 해제되고 종료된 상태
- running > ready
다른 프로세스에서 I/O 요청을 해서 인터럽트가 일어남
- running > waiting
I/O의 요청으로 반응을 대기하거나 무언가를 대기하는 상태
- waiting > ready
I/O의 결과가 오거나, 무언가를 기다렸는데 결과가 오면 전이됨
리눅스의 프로세스 상태(ps)
R: Runnable(실행할 수 있음 = ready)
S: Sleeping
T: Traced or Stopped 등...
running이 없는이유? ps 명령어조차도 프로세스이기 때문에 ps프로세스만 실행되고 있어서 running프로세스는 보이지 않는 것 (ps가 running 상태)
프로세스의 응용
Process Control Block(PCB)
프로세스 하나당 PCB하나를 부여한다
PCB의 구성
- PID: Process ID로 프로세스마다 구분하기 위한 고유식별 코드
- Process state: running, waiting, excuting등 프로세스의 실행 상태 저장
- Process counter: 다음에 실행할 명령어의 주소
- CPU register: 이 프로세스가 사용하는 레지스터나 CPU 레지스터
- CPU scheduler information: 실행 우선순위, CPU 점유 시간 등 실행시간과 관련된 정보
- Memory-management information: 해당 프로세스의 메모리 주소
- Accounting information: 어떤 권한, 계정으로 실행했는지에 대한 정보
- I/O status information: I/O 장치 할당 목록, 열린 파일 목록
Context Switch
- 직역하면 맥락 전환이고 실제로는 CPU는 프로세스를 하나밖에 실행못하므로 전환하는 과정을 의미 > Time Sharing 참조
Context Swtich 과정

- P0을 실행하다가 도중 인터럽트 발생 or 시스템콜 or terminate가 되어 idle상태로 전환
- OS는 idle된 시점 P0의 PCB를 저장
- 스케줄러는 우선순위에 의해 다음 실행프로세스를 P1로 지정
- OS는 P1의 PCB를 불러오고 P1을 idle상태에서 excuting상태로 전환시켜 실행
- 도중 인터럽트 or 시스템콜에 의해 idle상태로 전환
- OS는 idle된 시점 P1의 PCB를 저장
- 스케줄러는 우선순위에 의해 다음 실행프로세스를 P0로 지정
- OS는 아까 저장했던 P0의 PCB를 불러오고 P0를 idle상태에서 executing상태로 전환시켜 실행
- Context Swtich는 하드웨어 사양에 성능이 좌우
그래서 UltraSPARC사에서는 Multiple register을 개발개선된 메모리관리 기술로 좀 더 빠르게 Context Swtich를 하도록 IT기업에서 노력하고 있음
- 리눅스 기준 661시간에 약 2억 3700만번정도 Context Swtich (1초에 60회)
스케줄러
Long-term Scheduler (Job Scheduler)
프로세스를 ready queue로 옮기는 역할옛날에는 컴퓨터 메모리가 작아서 64kb램에 10kb 프로세스 10개를 실행하려고 하는데 그 중 6개 밖에 실행을 하지 못했다. Long-term이 어떻게 6개를 선정할 것인지 기준을 정했다.
요즘은 메모리가 크기도 하고 가상 메모리가 생기며 이 개념은 사장되었다.
Short-term Scheduler (CPU Scheduler)
ready queue에 올라와있는 프로세스를 CPU에 올려서 실행하는 역할
Medium-term Scheduler (Swapper)
6개가 선정되어서 이제 메모리 4kb가 남았다. 그런데 프로세스가 변수 동적할당으로 5kb를 요구해서 메모리가 부족한 상황이다. 이 때 어느 프로세스를 디스크로 내릴 것인지 정하는 역할
Queueing Diagram (Waiting Queue)
프로세스가 실행되다가 ready queue로 가는 경우I/O 장치의 요청
- fork a child(자식 프로세스 생성)
- wait for an interrupt(다른 프로세스의 I/O요청이나 시스템콜로 인터럽트발생)
프로세스 시스템콜
프로세스와 관련된 시스템콜
fork()
한 프로세스가 자신과 똑같은 자식 프로세스로 복사
exec()
이미 실행되고 있는 프로세스를 덮어씌워서 새로운 프로세스를 실행
exit()
자원을 반납하고(메모리 동적할당 해제) 종료
_exit()
그냥 바로 종료
abort()
비정상적으로 종료될 때 로그정보를 report하며 종료 -> exception handling
wait()
부모가 자식 프로세스를 기다려주는 함수 / 파라미터로 자식 프로세스의 pid
fork()의 과정
- 자식 프로세스(복사할 새로운 프로세스)의 PCB 생성
- 자식 프로세스가 위치할 메모리 공간 마련
- 부모 프로세스의 PCB정보와 완전 똑같은 정보를 자식 프로세스의 PCB로 초기화(PID만 다름)
- 자식 프로세스의 PCB를 ready queue로 위치
- 부모 프로세스는 자식 프로세스의 PID를 반환, 자식 프로세스는 0을 반환
fork()의 특징
- 자식 프로세스는 부모 프로세스의 모든 정보(부모가 사용하던 I/O 장치, 실행 상태 등)를 공유
- getppid(): 자식 프로세스 안에서 부모 프로세스의 pid 호출
- getpid(): 자신의 pid 호출
- pid: 부모인 경우 자식 프로세스의 pid, 자식인 경우 0
- 스케줄러에 의해 부모, 자식의 우선순위가 달라지기 때문에 출력 순서는 바뀔 수 있음
exec()과정
- 실행 중이던 프로세스를 중단
- 실행시키고자하는 프로세스와 파라미터를 불러옴
- 새로운 프로세스를 위해 모든 하드웨어 장치를 프로세스에 맞춰 초기화
- 새로운 프로세스의 PCB를 ready queue에 위치
fork와 exec, wait의 조합
- fork를 통해 자식 프로세스를 만들고 자식프로세스에서 exec을 한다
- exec의 프로세스가 끝나면 자식프로세스도 종료
- 계속 자식 프로세스를 wait하던 부모 프로세스도 종료
CreateProcess()
윈도우 프로세스 생성 시스템콜로 POSIX의 fork + exec1~2는 fork() 3~6이 exec()의 기능과 흡사
- 새로운 프로세스의 PCB 생성
- 새로운 프로세스가 위치할 메모리 공간 마련
- 파라미터의 prog에 있는 주소의 프로세스와 프로세스의 args를 불러옴
- args를 주소공간에 있는 메모리로 복사
- 새로운 프로세스를 위해 모든 하드웨어 장치를 프로세스에 맞춰 초기화
- 새로운 프로세스의 PCB를 ready queue에 위치
종료 시스템콜
- exit(): 사후처리를 하고(메모리 동적할당 해제) 종료
- _exit(): 바로 종료 / 사용자가 사용할 일이 거의 없음. 운영체제에서 사용
- abort(): 사후처리를 하고 종료하지만 비정상적으로 종료했을 때 로그를 report
- wait(): 부모가 자식의 프로세스를 기다림
zombie 프로세스
자식이 할 일을 끝냈는데 부모가 wait 종료처리를 안 해줘서 자식이 살아있는 경우
orpahn 프로세스
자식이 할 일을 하고있는데 부모가 도중 사라져버려서 자식이 살아 있는 경우
멀티 프로세스의 응용
크롬 브라우저
- 브라우저 프로세스는 소켓통신(html, css, 사진 등 파일을 다운받거나 유저가 post로 전송), ui제공
- 렌더러 프로세스는 탭 하나 하나에서 사용자에게 렌데링을 제공
- 플러그인 프로세스가 여러 플러그인들을 동작(크롬의 애드온 기능들)
- https: security한 http로 브라우저가 링크를 미리 열어보고 위험하면 사용자에게 경고를 띄움
모바일 – iOS와 안드로이드
- 과거 버전의 iOS는 한 개의 프로세스만 실행할 수 있었으나, 요즘은 멀티를 지원
- 애플은 편의성보다 완벽함을 추구하기에 과거에 멀티프로세스가 불안정했을 때 싱글패스만을 고집
- 안드로이드는 처음부터 멀티프로세스를 통해 멀티태스킹을 지원(리눅스 기반)
포그라운드와 백그라운드
- 포그라운드 프로세스: 눈 앞에 당장 보이는 프로세스
- 백그라운드 프로세스: 눈 앞에 보이지 않고 메모리상에 실행되고 있는 프로세스
프로세스간 통신방법
message passing
커널이 버퍼큐(message queue)를 만들어서 프로세스가 그 공간을 사용
- 장점: 프로세스 개발자는 데이터를 넣고 빼고만 하면 되기에 다른 코드를 구현할 필요가 없음
- 단점: 버퍼큐가 변할 때마다 context switch가 일어나기 때문에 커널의 오버헤드가 큼
shared memory
커널이 공유하는 메모리를 할당해주고 프로세스 개발자가 그 공간을 이용
- 장점: 커널이 공간만 마련해주고 그 이후 손 때기 때문에 하는 일이 없어서 오버헤드가 작음
- 단점: 프로세스 개발자는 shared memory와 프로세스가 통신하는 코드를 다 구현해야함
Bounded buffer problem
- Producer(데이터 송신자)가 버퍼에 계속 넣기만하면 버퍼 오버플로
- Consumer(데이터 소비자)가 버퍼의 데이터를 계속 받기만하면 버퍼 언더플로
이 두 개를 적절이 균형있게 스케줄러가 관리해야함
Socket 통신
- Socket 통신 또한 IPC와 유사한 과정
- 클라이언트는 신호를 보내고 서버는 감지하다가 답변을 해줌
Remote Procedure Call(RPC)
서버가 클라이언트 대신에 함수를 돌려주도록 도와줌
- 장점: 클라이언트의 자원소모와 오버헤드가 적음
- 단점: 클라이언트에서 바로 실행하는 것 보다 속도가 느림