프로세스와 관련해서 네 가지의 중요한 시스템콜에 대해서 정리한다.
프로세스 생성
우선 부모 프로세스가 자식 프로세스를 어떤 방식으로 생성하고, 어떠한 관계를 가지게 되는 지 알아봐야 한다.
부모 프로세스가 자식 프로세스를 어떤 방식으로 생성하는 지에 대해 가장 중요한 것은 복제생성이다.
부모 프로세스는 자신의 주소공간, PC register 등과 같은 정보들을 복제하여 자식 프로세스를 생성한다.
이와 같은 방식으로 생성되기 때문에 트리구조를 가지게 된다.
자식 프로세스의 생성은 굳이 두 가지로 나눠보자면,
1. 부모를 그대로 복사한다.
2. 복사한 자식 프로세스에 새로운 프로그램을 덮어 씌운다.
이와 같은 방식이라고 할 수 있을 것이다. 그렇다면 1번과 2번을 수행하는 시스템콜이 무엇이 있는 지에 대해 알아봐야 한다.
1번의 부모를 그대로 복사하는 기능의 시스템콜은 fork()가 있고, 2번의 새로운 프로그램을 덮어 씌우는 시스템콜은 exec()이 있다.
차례로 살펴 볼 것이다.
fork() 시스템콜
int main(){
int pid;
printf("1");
pid = fork();
if(pid == 0){
// 자식 프로세스
}
else if(pid > 0){
// 부모 프로세스
}
}
위와 같은 프로그램이 하나 있다고 가정해보자.
fork()라는 시스템콜을 명시적으로 호출하였다. 그럼 위 프로그램이 그대로 하나가 복제 되는 것이다.
즉, 아래와 같은 형태의 모습이 되는 것이다.
- fork() 시스템콜을 통하여 좌측의 부모 프로세스를 우측의 자식 프로세스와 같이 그대로 복사하는 것이다.
- 근데 여기서 자식 프로세스는 fork()이후부터 실행이 되는데, 그 이유는 위에서 설명 하였듯이 복제를 한다는 것이 부모 프로세스의 주소공간, PC register이기 때문에 자식 프로세스는 code영역의 어디를 실행시켜야 하는 지를 당연히 알고 있는 것이다.
- 이와 같이 자식 프로세스는 부모 프로세스와 같은 흐름을 가지는 프로그램이 되는 것이다.
하지만, 실제로는 다른 프로그램을 실행 시켜야 의미가 있는 것이고 그것을 위해 존재하는 시스템콜이 바로 exec()이다.
exec() 시스템콜
새로운 프로그램으로 덮어 씌워서 다른 프로그램을 실행 시킨다.
예를 들어 아래 코드르 살펴보자.
int main(){
int pid;
pid = fork();
if(pid == 0){
execlp("echo", "echo", "child", (char*)0);
}else if(pid > 0){
printf("parents!!");
}
}
- fork()시스템콜을 통해서 parent 프로그램을 복제한다.
- 복제한 child 프로세스에 다른 프로그램으로 덮어 씌우기 위해 exec()시스템 콜을 호출한다.
- parent 프로세스에서는 else if(){}가 실행 되는 것이고, child 프로세스에서는 echo 명령어를 실행하는 프로그램이 실행되게 되는 것이다.
위 코드에서는 fork()이후에 exec()시스템콜을 호출하였지만, fork()를 하지 않아도 된다.
하지만, 위 코드를 기준으로 fork()시스템콜을 호출하지 않았다면 "parents!!"는 평생 실행이 안될 것이다.
(parent 프로세스가 child에 덮히기 때문에.)
wait() 시스템콜
- 프로세스 A가 wait() 시스템콜을 호출.
- 커널은 child 프로세스가 종료될 때까지 프로세스 A를 sleep시킨다.(block상태)
- child 프로세스가 종료되면 커널은 프로세스 A를 Ready상태로 변경한다.
exit() 시스템콜
프로세스를 종료시키는 시스템콜이다.
프로세스의 종료
- 자발적 종료
- 마지막 statement 수행 후, exit() 시스템콜을 호출하는 것.
(예를 들어 main블럭이 return 되는 부분에서는 자동으로 컴파일러가 넣어준다.)
- 마지막 statement 수행 후, exit() 시스템콜을 호출하는 것.
- 비자발적 종료
- 부모 프로세스가 자식 프로세스를 강제 종료 시키는 경우
- 자식 프로세스가 한계치를 넘어서는 자원을 요청.
- 자식에게 할당된 태스크가 더 이상 필요하지 않을 때.
- 사용자에 의한 외부적 종료
- 부모가 종료하는 경우
- 부모 프로세스가 종료하기 전에 자식 프로세스가 먼저 종료됨.
- 부모 프로세스가 자식 프로세스를 강제 종료 시키는 경우
프로세스 협력
프로세스는 원칙적으로는 독립적이다.(독립적 프로세스)
각자의 주소공간을 가지고 수행되므로 하나의 프로세스는 다른 프로세스의 수행에 영향을 미치지 못한다.
하지만, 경우에 따라서 효율적인 실행을 위해 협력할 수 있다.(협력 프로세스)
프로세스간 협력 매커니즘(IPC: Interprocess Communication)
우선 프로세스간에 협력은 프로세스 간 직접적인 통신은 불가하므로 모두 커널을 통해서 이루어진다.
- 메시지 전달 방식(message passing)
- 커널을 통해 메시지 전달.
- 프로세스 사이에 공유변수를 전혀 사용하지 않고 통신하는 시스템.
- Direct Communication
- 통신하는 대상 프로세스의 이름을 명시적으로 표시(대상 O)
- Indirect Communication
- mailbox(or Port)를 통해 간접 메시지를 전달(대상 X)
- 주소공간을 공유하는 방식(Shared Memory)
- 서로다른 프로세스 간에도 일부 주소 공간을 공유하게 하는 메커니즘을 사용
(Shared Memory를 한다는 시스템콜을 커널에게 한 뒤, 매핑 후 사용자 프로세스끼리 공유.) - (예시)
A 프로세스의 주소공간, B 프로세스의 주소공간이 별도로 있지만,
물리적인 메모리에 매핑할 때, 일부 메모리가 공유 되도록 매핑.
- 서로다른 프로세스 간에도 일부 주소 공간을 공유하게 하는 메커니즘을 사용
메시지 전달 방식과 주소공간을 공유하는 방식의 차이.
(*참고) Thread간에 협력?
Thread는 사실 하나의 프로세스이므로 Thread간에는 주소공간을 공유한다.
그러니 당연히 협력이 가능한 것.
'ComputerScience > OS' 카테고리의 다른 글
4. 프로세스(2) (0) | 2022.12.26 |
---|---|
3. 프로세스(1) (0) | 2022.11.08 |
2. 컴퓨터시스템 구조(2) (0) | 2022.11.06 |
1. 운영체제란 & 컴퓨터시스템 구조(1) (0) | 2022.11.02 |
[OS] Process Memory와 Thread (0) | 2022.08.03 |