- 기본 프로세스 생성 과정
- TEXT, DATA, BSS, HEAP, STACK 의 공간을 생성
- 프로세스 이미지를 해당 공간에 업로드 하고 실행 시작
- 프로세스 계층
- 다른 프로세스는 또 다른 프로세스로부터 생성
- 부모 프로세스, 자식 프로세스
- 공간만들고
- 이미지 다운
- 실행 (stack/heap)
-
fork() 시스템 콜
- 새로운 프로세스 공간을 별도로 만들고, fork() 시스템콜을 호출한 프로세스(부모 프로세스) 공간을 모두 복사
- 별도의 프로세스 공간을 만들고 부모 프로세스 공간의 데이터를 그대로 복사
헤더 파일 : <unistd.h> 함수 원형 : pid_t fork(void); <- void 인자 없음#include <sys/type.h> #include <unistd.h> #include <stdio.h> int main(){ pid_t pid; print("Before fork() call \n"); pid = fork(); if(pid == 0) printf("This is Child process. PID is %d\n", pid); else if(pid>0) printf("This is Parent process. PID is %d\n", pid); else printf("fork() is failed \n"); return 0; }- pid = fork() 가 실행되면 부모 프로세스와 동일한 자식 프로세스가 별도 메모리 공간에 생성
- 자식 프로세스는 pid 가 0 으로 리턴, 부모 프로세스는 실제 pid 리턴
- 두 프로세스의 변수 및 PC(Program Count) 값은 동일
- 새로운 프로세스 공간을 별도로 만들고, fork() 시스템콜을 호출한 프로세스(부모 프로세스) 공간을 모두 복사한 후, fork() 시스템콜 이후 코드부터 실행
- 새로운 프로세스 공간을 별도로 만들고, fork() 시스템콜을 호출한 프로세스(부모 프로세스) 공간을 모두 복사
-
exec() 시스템 콜
-
exec() 시스템콜을 호출한 현재 프로세스 공간의 TEXT, DATA, BSS 영역을 새로운 프로세스의 이미지로 덮어 씌움
- 별도의 프로세스 공간을 만들지 않음
-
exec() 시스템콜 family
헤더 파일: <unistd.h> 함수 원형: int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char * const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *file, char *const argv[], char *const envp[]);- execl() 시스템콜
execl("디렉토리와 파일 이름이 합친 전체 이름", "명령어 인수 리스트", "끝은 NULL 로 끝나야 함");#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(){ printf("execute ls \n"); execl("/bin/ls","ls","-l", NULL); perror("execl is failed \n"); exit(1); }- execlp() 시스템콜
// 파일 이름을 해당 프로세스를 실행한 프로세스의 환경변수(path)를 검색함 execlp("파일 이름","명령어 인수 리스트", "끝은 NULL 로 끝나야 함");execlp("ls","ls","-al", NULL);- execle() 시스템콜
// 환경 변수를 지정하고자 할 때 char *envp[] = {"USER=dave", "PATH=/bin", (char *)0}; execlp("ls","ls","-al", NULL, envp);- execv() 시스템콜
// 인수 리스트를 내용으로 하는 문자열 배열 execv("/bin/ls", arg);- execvp() 시스템콜
// 파일 이름을 해당 프로세스를 실행한 프로세스의 환경변수 (path) 를 검색 // 인수 리스트를 내용으로 하는 문자열 배열 char *arg[] = {"ls", "-al", NULL}; execvp("ls", arg);- execve() 시스템콜
// 환경변수를 지정하고자 할때 char *envp[] = {"USER=dave", "PATH=/bin", (char *)0}; // 인수 리스트를 0내용으로 하는 문자열 배열 char *arg[] = {"ls", "-al", NULL, envp}; execve("ls", arg); -
-
wait() 시스템콜
-
fork(), excel(), wait() 시스템 콜
- execl() 만 사용하면 부모 프로세스 사라짐
- 이를 유지하기 위해 fork() 로 새로운 프로세스 공간 복사 후 execl() 사용
- wait() 함수를 사용해서 부모 프로세스가 자식 프로세스가 끝날 때까지 기다릴 수 있음
쉘 프로그램은 fork(), exec() 계열, wait() 함수를 기반으로 작성 가능
int main(){ int pid; int child_pid; int status; pid = fork(); switch (pid){ case -1: perror("fork is failed \n"); break; case 0: execl("/bin/ls", "ls", "-al",NULL); perror("execl is failed\n"); break; default: child_pid = wait(NULL); printf("ls is complete\n"); printf("Parent PID (%d), Child PID (%d) \n", getpid(), child_pid); exit(0); } }
- fork() 는 새로운 프로세스 공간 생성 후 기존 프로세스 공간 복사
4GB 를 복사한다면 프로세스 생성 시간이 오래 걸림



