프로세스
- 부모 프로세스가 자식 프로세스를 생성한다.
- 실제 족보처럼 프로세스 트리 구조를 형성하게 됨
- 프로세스는 자원이 필요하다.
- OS로부터 자원을 받는 모델
- 공유 X - 부모와 자식이 자원을 얻으려고 경쟁해야 함
- 부모와 공유하는 모델
- 수행 (Execution)
- 부모와 자식이 공존하며 수행되는 모델
- 자식이 종료될 때까지 부모가 기다리는(wait in blocked) 모델
프로세스 생성
- 자식은 부모의 주소 공간을 복사(binary & OS Data)하여 생성되고, 그 공간에 새로운 프로그램을 올린다.
- 부모의 문맥 (메모리 - code, data, stack / CPU - Program Counter Register) 를 모두 복사한다.
- ex) UNIX
- fork() 시스템 콜을 통해 새로운 프로세스를 생성한다.
- exec() 시스템 콜을 통해 새로운 프로그램으로 덮어써서 메모리에 올린다.
- ex) LINUX
- 리눅스 같은 경우는 자식 프로세스를 복사할 때 PC 만 복사했다가 write 가 정말 발생하면(내용이 바뀌면) 메모리에 전체 내용을 복사한다.
fork
- fork 를 부른 프로세스를 복제해서 새로운 주소 공간에 복사
int main() {
int pid;
pid = fork();
if (pid == 0)
printf("child\n");
else
printf("parent\n");
}
- fork 의 return 값은 자식의 경우 0 부모의 경우 양수 값.
- fork (부모2) 를 실행하면 OS 에 프로세스 만들어달라고 요청 -> 자식 프로세스 생성 -> 다음 라인 실행 (부모3 / 자식1)
- 부모의 문맥을 전부 복사하기 때문에 자식은 fork 다음 문장부터 실행됨.
exec
- exec 시스템콜로 프로세스가 다른 프로그램을 실행할 수 있게 덮어씌움.
- exec 실행 후엔 이전 프로그램으로 돌아갈 수 없음.
int main() {
int pid;
pid = fork();
if (pid == 0) {
printf("child\n");
execlp("/bin/date", "/bin/date", (char *)0);
printf("a");
}
else
printf("parent\n");
}
execlp("echo", "echo", "hello", "4", (char *)0);
wait
- 프로세스 A가 wait 시스템을 호출 시,
- 커널은 A의 child 가 종료될 때까지 A를 sleep (block)
- child 프로세스가 종료되면 커널이 A를 깨운다. (ready)
- 부모와 자식이 동시에 CPU 등 자원을 얻으려고 경쟁하지 않고, 자식이 종료되어야 부모가 실행된다.
- 리눅스 같은 경우, 기본 OS 프로그램이 떠있고 커맨드 라인으로 한번에 하나의 커맨드만 입력 가능한데 그런 경우가 이런 경우.
int main() {
int pid;
pid = fork();
if (pid == 0)
printf("child\n");
else
wait();
}
종료
- 프로세스가 마지막 명령을 수행한 후 운영체제에게 알린다. (exit)
- 자식이 부모에게 output data 를 보내고 (부모가 wait 중일 때) 죽음.
- 프로세스의 자원들이 OS 에 반납된다.
- 부모 프로세스가 자식의 수행을 종료시키는 경우 (abort)
- 자식이 자원을 너무 많이 먹음 (할당 자원 한계치를 넘음)
- 자식에게 할당된 태스크가 필요하지 않음
- 부모가 종료(exit)함
- OS는 부모 프로세스가 종료되면 자식도 다 종료시켜버림.
- 부모 exit -> 자식부터 죽고 -> 마지막에 부모가 죽을 수 있게 단계적 종료
exit
- 자발적 종료
- 프로그램에서 명시적으로 exit() 시스템 콜을 하거나,
- 명시적으로 적지 않아도 컴파일러가 main 함수가 리턴되는 위치에 넣어서 exit() 시스템 콜이 실행되는 경우
- 비자발적 종료
- 부모 프로세스가 자식 프로세스를 강제 종료시킴
- 자식의 한계치 넘는 자원 요청
- 자식 태스크가 필요 없음
- 키보드로 kill, break, ctrl + C 등을 쳐서 종료시키 경우
- 부모가 종료된 경우
프로세스 간 협력
독립적 프로세스
프로세스가 각자의 주소 공간을 가지고 수행되어서 독립적으로 실행됨.
협력 프로세스
프로세스 협력 메커니즘(IPC) 를 통해 프로세스가 서로의 수행에 영향을 끼침.
IPC (Interprocess Communication)
Message Passing
- 커널을 통해 메시지를 전달하는 방법
- 프로세스 사이에 공유 변수를 사용하지 않고 통신한다.
Direct Communication
- 통신하려는 프로세스의 이름을 명시적으로 표시해서 메시지 전송.
Indirect Communication (Mailbox)
- mailbox 나 port 를 통해서 메시지를 간접 전달한다.
Shared Memory
서로 다른 프로세스 사이에 일부 주소 공간을 공유
- 처음에 커널에 메모리 공유한다고 system call 보내서 공유 메모리 공간 받아야 한다.
- 두 프로세스가 신뢰 가능한 관계여야 수행할 수 있다. 만약... 한 프로세스가 말도 안되게 메모리를 쓰거나 악의적인 코드를 심는다면...😱
+) thread 의 경우 하나의 프로세스 내의 실행 단위 이므로 프로세스 간 협력은 아니지만, 동일 프로세스 내의 스레드는 메모리 주소 공간을 공유하기 때문에 협력이 가능하다.
출처 / 참고
반효경 교수님의 2014 운영체제 4. Process Management 1, 2 강의를 듣고 포스팅하고,
공룡책을 읽고 추가 정리합니다.
사진 출처는 강의 자료.