운영체제 - Process(5)
OS를 공부하면서 정리를 한 내용들 입니다.
이번 챕터는 Process에 관련해 정리한 챕터입니다.
Process(3)에 적었던 fork()와 exec() 시스템 콜에 대해 알아봅시다.
fork() 시스템 콜
int main()
{
int pid;
pid = fork();
if(pid ==0) /* this is child */
printf("\n Hello, Iam child\n");
else if(pid > 0) /* this is parent */
printf("\n Hello, Iam parent\n");
}
해당 코드가 2개 복사 되어있다고 생각해봅시다. (동일한 업무를 하는 프로세스)
처음에 실행되었을 때는 프로그램이 부모 프로세스 하나입니다. (아직 자식이 생성되지 않음)
쭉 실행을 하다가 fork()
를 만나면 새로운 프로세스(자식 프로세스)를 만들게 됩니다.
함수 실행이 끝났을 때 부모 프로세스는 끝까지 진행이 되고,
자식 프로세스에서는 메인함수의 시작부에서 부터 시작하는게 아니라,
fork()
를 실행한 그 이후부터 시작을 하게 됩니다.
프로세스의 fork()를 통한 복제 생성은 부모 프로세스의 문맥을 그대로 복사합니다.
그런데 세상에 같은 코드를 가지는 프로그램들만 존재할 수는 없습니다.
그래서 존재하는 시스템 콜이 exec()
시스템 콜입니다.
exec() 시스템 콜
int main()
{
int pid;
pid = fork();
if(pid ==0) /* this is child */
{ printf("\n Hello, Iam child Now I'll run Date\n");
execlp("/bin/date", "/bin/date", (char *)0);
}
else if(pid > 0) /* this is parent */
printf("\n Hello, Iam parent\n");
}
fork()
를 하고 자식 프로세스쪽에서 execlp()
를 사용하게 되는데
이것은 일종의 함수로, exec()
시스템 콜을 하게 됩니다.
exec()
를 만나게 되면 이제껏 실행되었던 프로그램은 기억을 잃고 main()
에서 새로 시작하는 것처럼
실행을 하게 됩니다.
execlp()
의 내부에 있는 것은 리눅스의 커맨드 혹은 프로그램입니다.
프로그램 date
를 2번 넣어주고, argument
를 넣어준 다음, null pointer를 넣어주게 하면 현재 시간을 알려줍니다.
이렇게 되면 완전히 date
라는 프로그램으로 새롭게 태어나게 됩니다.
wait() 시스템 콜
해당 프로세스를 잠들게 합니다.
wait()
는 보통 자식 프로세스를 만든 다음에 사용이 됩니다.
그렇게 되면 자식 프로세스가 종료되기를 기다리면서 block 상태가 되고
자식 프로세스가 종료되면 ready상태로 돌아가면서 CPU를 얻을 수 있게 됩니다.
exit() 시스템 콜
크게 2가지 종류로 구분합니다.
자발적 종료
-
마지막 statement 수행 후 exit() 시스템 콜을 통해
-
프로그램에 명시적으로 적어주지 않아도 main 함수가 리턴되는 위치에 컴파일러가 작성시켜줍니다.
비 자발적 종료
- 부모 프로세스가 자식 프로세스를 강제종료 시키는 경우
- 자식 프로세스가 한계치를 넘어서는 자원 요청을 할 때
- 자식에게 할당도니 태스크가 더 이상 필요하지 않을 떄
- 키보드로 Kill, break 등을 친 경우
- 부모가 종료하는 경우
- 부모 프로세스가 종료하기 전에 자식들이 먼저 종료됨.
이렇게 프로세스와 관련한 시스템 콜 4가지에 대해서 공부해 봤습니다.
-참고 Kmook 이화여자 대학교 반효경 교수님 : 운영체제 강의