fork( ), exec( ), wait( )와 같은 것들은 Process 생성과 제어를 위한 System call
새로운 프로세스를 생성할때 사용한다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
printf("pid : %d", (int) getpid()); // pid : 29146
pid_t pid = fork();
if (pid < 0) {
exit(1); // (1) fork 실패
}
else if (pid == 0) { // (2) child 인 경우 (fork 값이 0)
printf("child (pid : %d)", pid);
}
else { // (3) parent case
printf("parent (pid : %d)", pid);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
printf("pid : %d", (int) getpid()); // pid : 29146
pid_t pid = fork();
if (pid < 0) {
exit(1); // (1) fork 실패
}
else if (pid == 0) { // (2) child 인 경우 (fork 값이 0)
sleep(3)
printf("child (pid : %d)", pid);
exit(0);
}
else { // (3) parent case
int wc = wait(NULL);
printf("parent (pid : %d)", pid);
}
}
exec가 실행되면,
execvp( 실행 파일, 전달 인자 ) 함수는, code segment 영역에 실행 파일의 코드를 읽어와서 덮어 씌운다.
씌운 이후에는, heap, stack, 다른 메모리 영역이 초기화되고, OS는 그냥 실행한다. 즉, 새로운 Process를 생성하지 않고, 현재 프로그램에 echo 프로그램을 실행한다. 그로인해서, execvp() 이후의 부분은 실행되지 않는다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
printf("pid : %d", (int) getpid()); // pid : 29146
int rc = fork(); // 주목
if (rc < 0) {
exit(1);
} // (1) fork 실패
else if (rc == 0) { // (2) child 인 경우 (fork 값이 0)
printf("child (pid : %d)", (int) getpid());
char *myargs[3] = {"echo", "hello", "students",(char *)0}
// myargs[0] 내가 실행할 프로그램 이름
// myargs[1] 실행할 파일에 넘겨줄 argument
// myargs[2] end of array
execvp(myarges[0], myargs);
printf("this shouldn't print out") // 실행되지 않음.
}
else { // (3) parent case
int wc = wait(NULL) // 추가된 부분
printf("parent of %d (wc : %d / pid : %d)", wc, rc, (int)getpid());
}
}
fork()와 exec를 함께 수행하면 1개의 소스코드로 2개의 프로세스를 동작하도록 할 수 있다.