자료 출처 : KOCW 운영체제 - 반효경 교수님
process는 어떻게 만들어질까? 이 부분은 그냥 진리라고 생각하고 받아들이자. 이렇게 작동하도록 설계했다.
💡 Copy-on-write(COW)
사실 부모와 자원을 공유하지 않는게 원칙인데, 리눅스와 같은 운영체제에서는 이를 효율적으로 수행하기 위해 일단 공유부터 한다. PC만 따로 두고, 일단 쭉 진행하다가 수정해야할 부분이 생기면 그 부분들을 그제서야 따로 copy한다. 말 그대로 write해야할 때 copy하는 것이다.
각각의 과정을 조금 더 자세히 알아보도록 하자.
앞에서도 배웠듯이 process 하나 다루는게 어지간한 일이 아니다. 따라서 process가 바로 자식을 만들지는 않고, 운영체제에게 부탁한다.
두 단계를 거친다.
복제 생성은 fork()라는 system call로 이루어지며, 그 후 덮어 씌우는 과정은 exec()라는 system call로 이루어진다.
fork()를 통해 새 process를 생성한다. 정확히는 자신을 복사해 새로운 process를 생성하는 꼴이다.
int main(){
int pid;
pid = fork();
if(pid == 0)
printf("hi, i am a child\n");
else if(pid > 0)
printf("hi, i am a parent\n");
}
그런데 이렇게 fork만쓰면 제어 흐름(코드)이 완전히 같은(물론 조건문으로 분기는 되지만) 프로그램만 존재할 수 밖에 없다. 이를 위해 exec를 쓰는 것이다.
exec()을 통해 전혀 다른 프로그램을 실행할 수 있다. 실행된 process의 공간에 다른 process를 덮어씌운다.
int main(){
int pid;
pid = fork();
if(pid == 0){
printf("hi, i am a child. Now i'll run date\n");
execlp("/bin/data", "/bin/data", (char*)0);
}
else if(pid > 0)
printf("hi, i am a parent\n");
}
"hi, i am a child. Now i'll run date\n"
를 출력하고 execlp
에 의해 /bin/data
process로 바뀌게 된다.exit()
을 통해 운영체제에게 이를 알려준다. 자발적인 종료이다.
강제 종료
하는 경우도 있다. abort()
로 가능부모가 wait()을 호출했을 때 kernel은 자식이 종료될 때 까지 해당 부모를 blocked 상태
로 만들어 놓는다. 그 후 자식이 모두 종료되면 ready 상태
로 바꾼다.
int main(){
int pid;
pid = fork();
if(pid == 0){
// some child logic
}
else if(pid > 0){
// some parent logic
wait();
}
// logic
}
process를 종료시킬 때 호출하는 system call
기본적으로 process는 각자의 주소 공간을 가지고 수행되므로, 다른 process의 수행에 영향을 미치지 않는다.
그러나 필요한 경우 process들끼리 필요한 정보는 나누면서 일을 하게 만들고 싶을 수도 있다.(구체적인 예를 들어보고 싶은데 지식이 없다 ㅠㅠ)
이런 협력 메커니즘을 interprocess communication, IPC라고 한다.
process간 협력에는 크게 2가지 방법이 있다.
서로 다른 process간에 메세지를 전달
여기도 크게 두가지 방법이 있다. 하지만 둘다 커널이 중간에서 전달해준다는 것은 변함없는 사실
Direct Communication
Indirect Communication
일부 주소 공간을 두 process가 공유하게 만드는 방법
그림의 우측을 보면 빨간 상자와 노란 상자가 겹치는 부분이 있다. 저 부분이 shared memory
조금 더 정확히 말해보자. process들은 생성될 때 자신만의 메모리 공간을 갖게 된다. virtual memory를 떠올려라! 이 virtual memory를 physical memory에 mapping할 때, 저렇게 겹치게 mapping함으로써 shared memory를 확보한다.
이런걸 하려면 kernel에게 shared memory를 한다는 system call을 해야한다고 한다. 그러나 kernel이 한번 이어주면 그 후로는 알아서 신중하게 해야한다.