3-2 week3 -2
0.review
fork하는 순간에 프로세스가 생겨서 concurrent(병렬)하게 진행된다.
로컬변수 - 스택 pid, 부모는 자식의 pid를 주고, 자식의 pid에는 0 할당.
1.process exec(), wait()
새로운 프로그램 실행, 대체 바뀌어버린다.
3가지의 버전이 있다.
1)execl = bin밑에 ps실행시켜줘, 내가 실행하고 싶은 명령어의 위치, argument 봐라. -> main(int argc...여기 인자가 의미하는 바는 ./pexec aaa bbb 아 이게 argument임, argc는 3이 되고, argv[0] = "./pexec", argv[1] = " aaa", argv[2] = "bbb" (argument vector)
2)execlp = ps라는 프로그램이 어디있는지 쉘 니가 찾아서 실행시켜줘(환경변수) in PATH
3)execle = ps_envp를 가지고 와서 실행해라 PATH, TERM 등 고려한다.
tip. env: 환경변수가 다 보여진다.
4) execlv, execlvp, exelve = argv(argumentvector)을 배열로 미리 만들어놓는것. 사진보면 더 간단하게 작성가능
2. 예제
우선 예제를 보자 (3.27ppt)
pexec실행하는데 execlp 시스템콜을 만나면 다른 프로그램을 실행한다.
이때, ps가 사용자와 관련된 프로세스를 보여준다.
즉, pexec.c 프로세스는 사라져버리고 ps라는 프로세스가 올라오는거지.
ps는 명령어지만, /bin/ps 실행파일을 실행해주는 거야...! 마치 ./pexec처럼말이야
그림에서 보이듯이 execlp가 되는 순간 프로세스 없어지고, 다른 ps프로세스 실행
다 끝나면 ps도 끝나고 bash로 돌아오는거지.
(printf는 실행이 안되지 실행하는 순간 메모리 사라지니깐)
시험문제: 실행하면 무엇이 출력되는가?
3.
실습
cat pexec.c
gedit pexec. -> save 버튼 -> cat pexec.c -> gcc pexec.c -o pexec g(compile) -> ./pexec
ls명령어일떄는 파일옵션
바꿔서도 해보자!
ps를 넣으면....!? 사용자와 관련된 즉, 지금 내가내가내가 실행중인 프로세스 사진!!
시험문제: ls로 했을 때 출력되는 것은?
4.
system vs exec
exec는 프로그램이 돌아가다가 그게 죽고 다른 프로그램으로 바뀌는데
system은 child process를 만들고, 그 프로세스(별도의 메모리 공간)에서 쉘을 뛰운다. 거기서 ps라는 걸 실행시켜준다.
즉, parent process가 죽는 게 아니다. 그럼 재귀함수처럼 wait하다가 child끝나면 printf랑 exit함수 돌아가겠지.!
bash에서 system1불렀다! -> 임시 shell을 만들고 여기서 ps실행 다시 돌아오고 다음 줄로 옮긴다.
3.30 ppt 확인해보자!
5.
wait()
fork와 같이 쓰인다!!!
child process가 끝날 때까지 wait(&status)에 의하여 parent process가 기다린다.
그리고 wait에 의해서 return받는 것은 종료된 child process의 pid이다. 종료가 되었다는 정보를 제공한다.
-> 자 그러면 어떻게 끝났느냐? child가 parent에게 메시지를 주고 싶다면....이때 exit_code를 사용한다. 윗 줄의 종료가 되었다는 정보가 바로 이것! 이때, child의 pid를 리턴받고 또 정보를 받고 싶어서 포인터를 이용해서 status를 받는다.(16비트) 이때, 이 status의 내용을 전달해주는 메소드들이 macro로 구현되어있다. import wait.h
(개인적인 검색결과: 부모프로세스가 자식프로세스보다 먼저 끝나서 자식이 고아가 되는 것을 방지하기 위한 목적으로 보통 fork가 쓰이고 나서 wait메소드를 사용한다. 이때, wait의 인자인 status를 통해서 자식프로세스의 상태를 알 수 있다.)
(개인적인 검색결과2: pid가 0보다 작거나 0인 경우가 자식 프로세스를 뜻한다 그렇지 않은 경우는 부모프로세스인데 조건문을 통해서 부모프로세스임을 알았다면 거기서 wait메소드를 사용하고 &status를 통해서 자식 프로세스의 정보를 보내준다.
(개인적인 검색결과3: 자식 프로세스가 종료하면 부모프로세스에게 시그널을 보낸다.)
*참고
wkdtjsgur100.github.io/process-system-call/
6.
사용법한번봅시다(3.34 ppt)
sys/wait.h를 include하는 이유는 macro를 쓰려고!
pid가 0이 아니니깐 parent고 wait를 불렀으니깐 5초간 그 코드에서 기다린다.!
이때 리턴되는 건 child의 pid
(아니 왜 또 child's pid냐? 왜냐하면 사실 fork를 여러번 쓰면 child가 많아져서 wait를 통해 구분할 수가 있어 먼저끝난 child를
둘 다 기다리려면 wait를 두 번 부른다.)
이 코드상에서는 fork에 의한 pid나 child_pid나 같겠지?
child는 exitcode = 37인데 그걸 부모에게 알리려면, &stat_val에서 받는다
(c언어 구조상 두개를 리턴할 수 없으니깐 포인터를 이용한다. 그게 stat_val)
여기서, api로 준다. stat_val값을 직접 읽어주는 걸 macro로 만들어놨다
(매크로함수를 만들어놓고 wait.h를 import, 상위 2개중에 2번째가 정상적으로 종료하고 exitcode를 리턴한다.)
(40분 다시 보기!) 이해x
exitcode = 0정상, 1비정상
37은 10진수 -> 25는 16진수
**과제:쉘만들기
과제는 명령어 많이 쓰라잉~
1)프롬프트는 내 이름
2)fork()해서 child process에서 exec(), argument(?)
3) child process 끝날때까지 기다린다.
4) 쉘만들기
5) 원래 쉘에는 잘동작하는데 내가 만든 쉘에는 잘동작하는 경우도 있고 아닌 경우도 있따.
왜 그럴까????
'이제는 사용하지 않는 공부방 > Operating system' 카테고리의 다른 글
[운영체제] thread = 실 (0) | 2020.09.21 |
---|---|
[운영체제] process creation3 (0) | 2020.09.16 |
[운영체제] process creation (0) | 2020.09.16 |
[운영체제] 리눅스란 (0) | 2020.09.12 |