유닉스 환경에서 프로세스를 생성시키는 명령어는 fork()
와 exec()
가 있다.
두 명령어 모두 한 프로세스가 다른 프로세스를 실행시키기 위해 사용하게 된다.
fork()
는 새로운 프로세스를 위한 메모리를 할당한다. 그리고 fork()
를 호출한 프로세스의 PCB 정보을 새로운 공간으로 전부 복사하게 되고, 원래 프로세스는 기존 작업을 계속 실행하게 된다. fork()
로 생성된 프로세스 또한 fork()
시스템 콜이 수행된 라인의 다음 라인부터 실행된다. (새로 생성된 프로세스는 원래의 프로세스와 똑같은 코드를 가지게 된다.)
exec()
는 fork()
처럼 새로운 프로세스를 위한 메모리를 할당하지 않고, exec()를 호출한 프로세스가 아닌 exec()
에 의해 호출된 프로세스만 메모리에 남게된다.
fork()
=> 프로세스를 하나 더 생성시킴 (PID가 다른 또 하나의 프로세스를 생성)
exec()
=> 새로운 프로세스에 PID가 그대로 적용되며,exec()
를 호출한 프로세스는 새로운 프로세스에 의해 덮어 쓰여짐.
하나의 프로그램이 실행하는 도중에 fork()
명령어를 실행하게 되면 동시에 두 개의 프로그램으로 나누어져 실행하게 된다.
이때 새로운 프로그램을 생성시킨 프로그램을 부모 프로세스(Parent process), 생성된 프로그램을 자식 프로세스(Child process)라고 한다. 즉, 부모 프로세스가 fork()
명령어를 실행하게 되면 부모와 똑같은 자식 프로세스가 생성된다.
리턴값 | 의미 |
---|---|
-1 | fork 명령어 오류 |
0 | 자식 프로세스 |
양수 | 부모 프로세스 |
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
int pid;
int status;
pid = fork(); // -1 : 에러 | 0 : 자식 | (양수) : 부모
if (pid < 0) {
// 에러
}
else if (pid == 0) { // 자식 프로세스
printf("Child: %d, Parent: %d\n", getpid(), getppid());
exit(3);
}
else { // 부모 프로세스
wait(&status);
printf("Parent: %d Child: %d\n", getpid(), pid);
printf("Status: %d", status>>8);
}
return 0;
}
Child : 1708, Parent : 1707
Parent : 1707 Child : 1708
Status: 3
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
char *cmd = read_command();
int pid;
if ( (pid=fork()) == 0 ) { // 자식 프로세스
exec(cmd); // 불러운 command 실행
}
else { // 부모 프로세스
wait(pid);
}
return 0;
}
cmd에 등록된 프로그램을 실행한 뒤, 해당 프로그램을 종료하면
부모 프로세스 또한 같이 종료된다.
https://chlgpdus921.github.io/operating%20system/Chapter2_Process2/
https://woochan-autobiography.tistory.com/207