프로세스의 개념
프로세스란 실행되고 있는 프로그램이다.
프로세스의 문맥(context)
프로세스를 설명하려면 문맥이 필요하다. 크게 3가지로 나눌 수 있다.
좌측 하드웨어, 우상측 주소공간, 우하측 커널 자료구조
하드웨어 문맥
프로세스에 대한 CPU 수행 상태를 나타내는 것은 하드웨어 문맥이라고 부른다. 각종 레지스터를 일컫는다.
어디까지 실행하였는가? 이 내용을 담고 있는 것이 Program Counter라는 레지스터이다.
이 명령어는 어떤 논리로 처리해야 하는가? 이것은 ALU(arithmetic logic unit)라는 레지스터에 담겨있다.
이런 식으로 프로세스의 상태를 알려면 CPU 수행 상태가 담긴 하드웨어 문맥을 읽어야 한다.
프로세스의 주소 공간
프로세스가 가지고 있는 코드와 데이터, 그리고 로직을 수행하는 스택을 일컫는다.
프로세스 관련 커널 자료구조
PCB
PCB(Process Control Block)는 프로세스의 상태에 대한 데이터가 담겨있는 자료구조이다.
커널 스택
커널 스택(Kernel stack)은 프로세스가 커널(OS 코드)를 호출 했을 때, 해당 메서드가 실행되는 프로세스만의 스택을 일컫는다. 다른 프로세스도 OS를 호출 할 것이기 때문에, 서로 섞이고 꼬이는 것을 방지하기 위해 각 프로세스마다 고유한 커널 스택이 있다.
프로세스의 상태
Running
CPU를 잡고 instruction을 수행중인 상태
Ready
CPU를 기다리는 상태(메모리 등 다른 조건을 모두 만족하고)
Blocked (wait, sleep)
•
CPU를 주어도 당장 instruction을 수행할 수 없는 상태
•
Process 자신이 요청한 이벤트(ex. I/O)가 만족되지 않아 기다리는 상태
•
Swap 공간에 있는 메모리에 접근할 때도 Blocked가 된다! (디스크에서 파일을 읽어와야 하는 경우이므로)
Suspended (stopped)
•
외부적인 이유로 프로세스의 수행이 정지된 상태
•
프로세스는 통째로 디스크에 Swap out 된다.
•
기타
New : 프로세스가 생성중인 상태
Terminated : 수행(execution)이 끝난 상태
프로세스의 상태 변화
간략한 프로세스의 상태 변화도
상태 변화도 2, suspend와 커널모드 내용이 추가되어 있다.
1.
생성 : 프로세스가 생성 중이다.
2.
실행 : 명령어들이 실행되고 있다.
3.
대기 : I/O 작업이나 공유 데이터에 접근하는 작업(기다려야 하는)가 일어나기를 기다린다.
4.
준비 : 프로세스가 처리기(cpu)에 할당되기를 기다린다.
5.
종료 : 프로세스가 실행이 종료되었다.
•
Suspended Block 과 Suspended Ready
◦
서스펜드는 메모리에 프로세스를 완전히 제거된 상태(Swap Out)를 나타낸다. 그러나 IO 작업등이 진행되었다고 하면, 이벤트를 받아 Suspended Ready 상태가 될 수 는 있다. 그러면 Swap In 과정을 통해 다시 메모리에 로드되어 실행가능한 상태가 될 수 있다.
PCB 블록
Process Control Block 은 운영체제가 각 프로세스를 관리하기 위해 프로세스 당 유지하는 정보를 나타낸다.
다음의 구성 요소를 가진다 (구조체로 유지 된다.)
구성요소 톺아보기
1.
프로그램 카운터(program counter)
•
프로그램 카운터는 이 프로세스가 다음에 실행할 명령어의 주소를 나타낸다.
2.
CPU 레지스터들
•
CPU 레지스터는 컴퓨터의 구조에 따라 다양한 수와 유형을 가진다.
◦
◦
프로그램 카운터 + 상태정보는 프로세스가 다시 스케줄 될 때 계속 올바르게 실행되도록 하기 위해서 인터럽트 발생 시 업데이트 되어야 한다.
3.
CPU 스케줄링 정보
•
이 정보는 프로세스 우선순위, 스케줄 큐에 대한 포인터와 다른 스케줄 매개변수를 포함한다.
4.
메모리 관리 정보
•
이 정보는 운영체제에 의해 사용되는 메모리 시스템에 따라 기준(base) 레지스터와 한계(limit)레지스터의 값, 페이지 테이블, 세그먼트 테이블 등과 같은 정보를 포함한다.
5.
회계(accounting) 정보
•
이 정보는 CPU 사용 시간과 경과된 실시간, 시간제한, 계정 번호, 잡 또는 프로세스 번호 등을 포함한다.
6.
입출력 상태 정보
•
이 정보는 프로세스에 할당된 입출력 장치들과 열린 파일의 목록 등을 포함한다.
문맥 교환
Context Switch, CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정
CPU가 다른 프로세스에게 넘어갈 때 운영체제는 다음을 수행한다.
•
CPU를 내어주는 프로세스의 상태를 PCB에 저장 (프로그램 카운터 정보, 메모리 맵 등)
◦
나중에 CPU를 다시 활용할 때 어느 위치부터 읽어야 하는지 알아야 하니까!
•
CPU를 새롭게 얻는 프로세스의 상태를 PCB에서 읽어옴
위 flow를 다이어그램으로 정리하면 다음과 같다.
System call이 발생하면 context switch일까?
시스템 콜이나 인터럽트가 발생 시 반드시 context switch가 일어나는 것은 아니다.
위에서 서술했듯이 한 프로세스에서 다른 프로세스로 넘기는 과정을 문맥 교환이라고 하기 때문에, 단순히 커널 함수를 처리하고(시스템 콜로 인해) 해당 프로세스로 복귀한다면 문맥 교환이라고 하지 않는다.
아래 캡션에 주목하자. 컨텍스트 스위칭은 단순 커널모드 진입보다 비용이 훨씬 크다
프로세스 스케줄링
시분할 프로그래밍에서 중요한 것은 프로세스들 사이에서 CPU를 빈번하게 교체하는 것이다. 프로세스 스케줄러는 실행가능한 여러 프로세스 중에서 하나의 프로세스를 선택한다. CPU 코어는 한 번에 하나의 프로세스를 실행할 수 있다. 만약 코어가 여러개라면 한 번에 여러개의 프로세스를 실행할 수 있다. 코어 수 보다 더 많은 프로세스가 있는 경우 초과 프로세스는 코어가 다시 사용 가능해지고 스케줄 될 때 까지 기다려야 한다.
프로세스 스케줄링을 위한 큐
1.
Job Queue
•
현재 시스템 내에 있는 모든 프로세스의 집합
2.
Ready Queue
•
준비 큐
•
현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
•
프로세스가 생성되면 준비 큐에 들어간다.
3.
Device Queues
•
입출력장치 대기 큐
•
I/O 디바이스의 처리를 기다리는 프로세스의 집합
큐 동작원리
프로세스가 시스템에 들어가면 준비 큐에 들어가 준비 상태가 되어 CPU 코어에서 실행되기를 기다린다. Linked list 구조 이기 때문에 준비 큐 헤더에는 리스트의 첫 번째 PCB에 대한 포인터가 저장되고, 각 PCB에는 준비 큐의 다음 PCB를 가리키는 포인터 필드가 포함된다.
CPU를 사용하던 프로세스가 I/O 요청과 같은 특정 이벤트가 발생할 경우, 실행 상태에서 벗어나 대기 큐에 삽입된다. 이벤트가 종료되면(ex. 디스크에서 데이터 읽어왔음) 준비 큐에 다시 삽입되어 CPU 할당을 기다린다.
아래는 프로세스 스케줄링 동작원리를 보여주는 큐잉 다이어그램이다.
1.
프로세스가 I/O 요청을 공표한 다음 I/O 대기 큐에 놓일 수 있다.
2.
프로세스는 새 자식 프로세스를 만든 다음 자식의 종료를 기다리는 동안 대기 큐에 놓일 수 있다.
3.
인터럽트 또는 타임 슬라이스(타이머 인터럽트)가 만료되어 프로세스가 코어에서 강제로 제거되어 준비 큐로 돌아갈 수 있다.
스케줄러의 종류
•
장기 스케줄러 (Long-term scheduler, job scheduler)
◦
시작 프로세스 중 어떤 것들을 준비 큐로 보낼 지 결정
◦
프로세스에 memory(및 각종 자원)을 주는 문제
◦
degree of multiprogramming(메모리에 올라가는 프로세스의 수)을 제어
◦
time sharing system에서는 보통 장기 스케줄러가 없음(무조건 ready)
•
단기 스케줄러 (Short-term scheduler, CPU scheduler)
◦
어떤 프로세스를 다음번에 running 시킬지 결정
◦
프로세스에 CPU를 주는 문제
◦
충분히 빨라야 함 millisecond 단위)
•
중기 스케줄러 (Medium-Term scheduler, Swapper)
◦
프로세스에게서 메모리를 빼았는 문제
▪
여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄
◦
degree of multiprogramming을 제어
▪
time sharing system에서 장기 스케줄러의 역할을 하는 셈
degree of multiprogramming?
메모리에 올라가있는 프로세스의 개수를 의미한다. 다중 프로그래밍에선 메모리에 여러 프로세스가 올라가 있어야 CPU가 돌아가며 실행할 수 있다. 하지만 너무 많은 프로세스가 메모리에 올라가 있으면(메모리를 너무 잘게 쪼개어 쓰면) 프로세스 실행에 필요한 명령어도 디스크 쪽에 있을 수 있다. 그러면 디스크로 접근하는 스왑핑이 너무 자주 일어나기 때문에, 메모리에 올라가 있는 프로세스가 적절한 개수로 조절되는 것이 필요하다.
부모 프로세스와 자식 프로세스
프로세스 생성의 특징
생성하는 프로세스를 부모 프로세스, 생성되는 프로세스를 자식 프로세스라고 한다.
•
프로세스는 자원을 필요로 함
◦
운영체제로부터 받음
◦
부모와 공유함
•
자원의 공유
◦
Copy-on-write (COW) 기법
▪
내용이 바뀔 때 새로운 걸 만들고, 그 전까지는 부모 것을 공유하는 것.
◦
부모와 자식이 모든 자원을 공유하는 모델
◦
일부를 공유하는 모델
◦
전혀 공유하지 않는 모델
•
수행
◦
부모와 자식은 공존하며 수행되는 모델
◦
자식이 종료될 때 때까지 부모가 기다리는 모델
프로세스 생성과 관련된 시스템콜
유닉스 OS - fork, exec, wait, exit
•
fork, 복사를 통한 자식 생성
◦
fork() 시스템 콜이 새로운 프로세스를 생성
▪
부모를 그대로 복사 (OS data except PID + binary)
▪
주소 공간 할당
◦
fork의 흐름
1.
프로그램이 fork()를 호출하면 OS는 프로세스를 그대로 복제해 새로운 주소공간을 할당한다. fork를 실행한 시점에서의 문맥이 동일하게 복제되기 때문에(프로그램 카운터까지), 부모와 자식 모두 fork 다음 라인의 로직을 수행한다.
2.
그렇다면 둘은 동일한데 어떻게 부모인지 자식인지 구분할까? fork() 메서드의 리턴값이 부모인 경우 양수(자식의 pid)가, 자식인 경우엔 0이 리턴된다. 위 이미지를 보면, 부모는 pid 3456를 리턴받았고, child는 0을 리턴받은 예시를 볼 수 있다. 이 값을 기준으로 분기하여 처리할 수 있다.
•
exec, 새로운 이미지를 덮어 쓰기
◦
exec() 시스템콜을 실행하면 새로운 프로그램을 실행한다.
◦
새로운 메모리 공간을 할당하는 것이 아니라 새로운 프로그램으로 덮어쓰게 된다. 이 말은, exec() 시스템 콜을 통해 호출된 프로세스가 종료되더라도 직전 프로세스로 돌아가지는 않는다는 말이다.
int main(){
printf("1");
// execlp 는 프로세스를 exec()하는 함수이다.
execlp("echo", "echo", "3", (char *)0);
printf("2");
}
/* 실행결과
* 1
* 3
* (end, 2는 실행되지 않음)
*/
C
복사
•
wait, 자식이 끝날 때 까지 대기
◦
프로세스 A가 wait() 시스템 콜을 호출하면
▪
커널은 자식이 종료될 때 까지 프로세스 A를 sleep 시킨다. (block 상태로 만든다)
▪
Child Process가 종료되면 커널은 프로세스 A를 깨운다. (ready 상태로 만든다)
◦
리눅스 터미널도 wait() 시스템 콜의 일종이다.
▪
프롬프트에 program 이름을 치면, 자식이 실행되는 동안 프롬프트에 명령어를 입력할 수 없다. (wait() → block 상태)
▪
program이 끝나면, 프롬프트에 다시 명령어를 입력할 수 있게 된다. (ready 상태)
•
exit, 모든 자원의 할당 해제; 부모에게 알림
◦
자발적 종료
▪
마지막 statement 수행 후 exit() 시스템 콜을 통해서 종료
▪
프로그램에 명시적으로 넣어주지 않아도 main 함수가 리턴되는 위치에 컴파일러가 넣어줌
◦
비자발적 종료
▪
부모 프로세스가 자식 프로세스를 강제 종료시킴 (abort)
•
자식이 할당 자원의 한계치를 넘어섬
•
자식에게 할당된 태스크가 더 이상 필요하지 않음
▪
키보드로 kill, break 등을 친 경우
▪
부모가 종료(exit)하는 경우
•
운영체제는 부모 프로세스가 종료하는 경우 자식이 더이상 수행되도록 두지 않는다.
•
단계적인 종료 (자식의 자식이 있는 경우)
프로세스간 협력
프로세스의 종류
•
독립적 프로세스 (Independent process)
◦
프로세스는 각자의 주소 공간을 가지고 수행되므로 원칙적으로 하나의 프로세스는 다른 프로세스의 수행에 영향을 미치지 못함
•
협력 프로세스 (Cooperating process)
◦
프로세스 협력 메커니즘을 통해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있음
•
프로세스 간 협력 메커니즘 (IPC : interprocess Communication)
◦
메시지를 전달하는 방법
▪
message passing : 커널을 통해 메시지 전달
◦
주소 공간을 공유하는 방법
▪
shared memory : 서로 다른 프로세스 간에도 일부 주소공간을 공유하게 하는 shared memory 메커니즘이 있음
협렵 메커니즘
Message Passing
•
프로세스 사이에 공유 변수(shared variable)를 일체 사용하지 않고 통신하는 시스템. 직접 전달하는 것이 아니라, 커널을 통해 전달하는 것임
Direct Communication
◦
통신하려는 프로세스의 이름을 명시적으로 표시 (직접 전달 아님)
Indirect Communication
◦
mailbox (또는 port)를 통해 메시지를 간접 전달
Shared Memory
•
system call을 통해 두 개의 프로세스가 주소공간을 공유하도록 하는 방식.
•
동시성 문제가 발생할 수 있으므로, 두 프로세스간은 믿을만한 관계여야 함
두 방식의 차이점
커널을 통하여 메시지를 전하느냐, 물리적인 메모리를 같이 사용하느냐 는 차이가 있음.
레퍼런스
반효경 교수님 프로세스 1강
프로세스 관리 2강
운영체제 10판 (공룡책)