이화여대 반효경 교수님의 강의, 유튜브 주니온님의 운영체제 강의 내용들을 정리한것
os는 프로세스 생성, 종료를 위한 메커니즘을 제공
프로세스는 여러 개의 새로운 프로세스를 생성할 수 있음
프로세스 트리
두 가지의 실행 방식
주소 공간의 두 가지 방식
int main()
{
pid_t pid; //프로세스 id
pid = fork(); //fork child 프로세스
if(pid < 0){// error 발생
fprintf(stderr, "Fork Failed");
return 1;
}
else if(pid==0){ //child 프로세스
execlp("/bin/ls","ls",NULL);
}
else { //parent process
wait(NULL);
printf("Child Complete(Terminated)")
}
return 0;
}
프로세스의 종료
zombi, orphan 프로세스
orphan process.c
int main() {
pid_t childPid;
int i;
childPid = fork();
if(childPid > 0) { // 부모 프로세스
printf("부모 PID : %ld, pid : %d\n",(long)getpid(), childPid);
sleep(2);
printf("부모 종료\n");
exit(0);
}
else if(childPid == 0){ // 자식 코드
printf("자식 시작\n");
for(i=0;i<10;i++) {
printf("자식 PID : %ld 부모 PID : %ld\n",(long)getpid(), (long)getppid());
sleep(1);
}
printf("자식 종료\n");
exit(0);
}
else { // fork 실패
perror("fork Fail! \n");
return -1;
}
return 0;
}
실행 결과
고아 프로세스가 작업을 종료하면 init 프로세스가 wait함수를 호출하여 고아 프로세스의 종료 상태를 회수함으로써 좀비 프로세스가 되는것을 방지함
fork().c
int main(){
pid_t pid;
pid = fork();
if( pid > 0){
printf("부모 프로세스 실행 중 pid = %d\n", pid);
}
else if(pid == 0){
printf("자식 프로세스 실행 중 pid = %d\n", pid);
}
return 0;
}
실행 결과
wait().c
int main(){
pid_t pid;
pid = fork();
if( pid > 0){ //부모 프로세스
wait(NULL);
}
printf("pid = %d\n", pid);
return 0;
}
실행 결과
wait().c 과정
waitpid()
자식 프로세스가 종료될 때 까지 차단되는 것을 원하지 않을 경우, 옵션을 사용하여 차단을 방지함 또 기다릴 자식 프로세스를 좀더 상세히 지정 가능
pid_t waitpid(pid_t pid, int *status, int options);
인자로 주어진 pid 번호의 자식 프로세스가 종료되거나, 시그널 함수를 호출하는 신호가 전달될때까지 waitpid 호출한 영역에서 일시 중지
만약 pid로 지정한 자식이 waitpid 호출전에 이미 종료됐으면,함수는 즉시 리턴하고 자식 프로세스는 좀비프로세스로 남게됨
pid 값
int main(){
pid_t pid;
pid = fork();
if( pid == 0){
execlp("/bin/ls","ls",NULL);
printf("LINE J\n");
}
else if(pid>0){
wait(NULL);
printf("Child Complete\n");
}
return 0;
}
실행 결과
자식 프로세스의 context는 execlp로 인해 부모 프로세스의 복사본에서 execlp()에 의해 호출된 프로세스의 context로 바뀜(덮어쓰기)
그래서 execlp() 다음 명령어인 Line J는 출력이 안됨(부모프로세스는 if문에 의해 출력못하고..) 그 대신에 ls명령어가 실행됨(실제 ls명령어 결과하고 같다)
Reference
주니온 교수님 유튜브 채널
반효경 교수님 KOCW 운영체제