System Call Error Handling
당연히 System Call을 할 때 Error가 발생할 수 있기 때문에 Error 처리를 해줘야 한다.
※System call에서 Exception만이 void return 값을 갖는다.
Creating and Terminating Processes
Process state는 4가지가 있다.
- Running - 현재 CPU에 의하여 실행되고 있는 상태이다.
- Waiting - Scheduling이 된 상태로 대기 중인 상태이다.
- Blocked (Stopped) - Scheduling이 되지 않은 상태로 Signal이 와야 Scheduling이 된다. Signal이 오지 않는다면 Scheuling이 될 수 없다.
- Terminated - 다시는 실행되지 않을 상태이다.
Creating Process
Parent process는 fork 함수를 이용하여 Child process를 만들 수 있다.
Fork() 함수를 이용하여 만들어진 Child process는 Parent process와 완전히 같은 내용을 담고 있다.
개별적인 Process가 만들어진 것이기 때문에 위 코드의 결과 값은 비확정적이다.( Child process가 먼저 실행되고 종료 될 수 있다. )
#include <stdio.h>
#include <unistd.h>
void fork4(){
printf("L0\n");
if(fork()!=0){
printf("L1\n");
if(fork()!=0){
printf("L2\n");
}
}
printf("Bye\n");
}
int main(){
fork4();
return 0;
}
위 코드의 Process Graph는 다음과 같다.
위 코드의 결과 값은 비확정적이나 나올 수 없는 순서(Infeasible output)가 존재한다.
Reaping Child Processes
Child Process가 terminte되면 CPU가 실행을 못하게 될 뿐이지 메모리에는 계속 올라와 있어 메모리 누수가 발생한다.
이렇게 terminate 되었지만 메모리에 올라와 있는 Process를 Zombie라고 부른다.
어떻게 하면 zombie process를 없앨 수 있을까?
Zombie process를 없애는 작업은 wait이나 waitpid를 사용하여 terminated child process의 Parent process가 하게 된다.
만약 Parent process가 child를 reap하지 않고 terminate된다면 메모리에서 제거 될 수 없는 Orphaned child가 생기게 되는데 wait을 사용하면 Orphaned child가 생기는 것을 방지 할 수 있다.
Wait : Synchronizing with Children
Wait을 사용하게 되면 Parent가 Child를 기다리게 된다. Process들이 종료되는데 순서가 생긴다는 의미이다.
#include <stdio.h>
#include <unistd.h>
void fork9(){
int child_status;
if(fork()==0){
printf("HC : hello from child\n");
exit(0);
}else{
printf("HP : hello from parent\n");
wait(&child_status);
printf("CT : child has terminated\n");
}
printf("Bye\n");
}
int main(){
fork9();
return 0;
}
위 코드는 Parent가 fork를 한 이후에 Chid를 기다리고 있다. 따라서 Bye는 무조건 마지막에 출력되야 한다.
execve: Loading and Running Programs
execeve 함수는 fork된 child process에서 부모코드가 아니라 새로운 파일을 실행하고 싶을 때 사용하는 코드이다.
int execeve(char *filename, char *argv[], char *envp[]) 3가지 변수를 받는다.
argv에는 argument의 list가 들어간다. argv[0]은 filename으로 고정이다.
envp에는 environment variable이 list로 들어간다.
※아래는 "/bin/ls -lt /usr/include"를 child process에서 execeve 할 때 stack의 구조이다.
'4-1 > 시스템프로그래밍' 카테고리의 다른 글
Unix I/O, RIO package (0) | 2022.04.04 |
---|---|
Signal (0) | 2022.03.28 |
Shell (0) | 2022.03.22 |
Processes (4) | 2022.03.10 |
Exceptional Control Flow, Exception (0) | 2022.03.09 |