[OS] 쉘과 init.c, fork-exec
- [ CS기초 ]/운영체제
- 2022. 9. 8.
//init.c 일부
for(;;){
printf(1, "init: starting sh\n");
pid = fork();
if(pid < 0){
printf(1, "init: fork failed\n");
exit();
}
if(pid == 0){
exec("sh", argv);
printf(1, "init: exec sh failed\n");
exit();
}
while((wpid=wait()) >= 0 && wpid != pid)
printf(1, "zombie!\n");
}
init.c는 xv6에서 가장 먼저 실행되는 user-level 프로그램이다. make-qemu를 통해서 xv6를 실행하면 init:starting sh라는 메세지와 함께 쉘이 실행된다.
init.c에는 무한루프가 존재하고, 그 안에서 fork-exec을 통해서 프로세스를 분리한다. fork함수는 성공시 부모 프로세스에는 자식 프로세스의 pid를, 자식 프로세스에게는 0을 리턴하므로, 위 코드에서 자식 프로세스에서 쉘("sh")을 exec함을 알 수 있다. (쉘도 하나의 프로세스이다)
그런데 쉘 프로세스는 segfault와 같이 모종의 이유로 종료되어서는 안된다. 따라서 부모 프로세스는 wait()을 통해서 자식 프로세스의 종료를 대기하며, 비정상적으로 종료될 경우 다시 무한루프를 돌아서 쉘을 다시 실행시킨다. 정상적으로 종료될 경우(wpid가 fork시 생성된 자식 프로세스의 pid와 동일할 경우) 좀비상태가 된다.
따라서 만약, init.c와 쉘 사이에 로그인 프로세스같이 프로세스를 추가하고 싶은 경우, 해당 프로세스에도 무한루프 안에 fork-exec을 사용해주면 추가한 프로세스가 (비정상)종료되어도 다시 실행되게 된다.
'[ CS기초 ] > 운영체제' 카테고리의 다른 글
[OS] 멀티쓰레드와 멀티프로세스, 멀티코어 (0) | 2024.06.30 |
---|---|
[OS] xv6 사용법 정리 (0) | 2022.09.07 |