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) 원래 쉘에는 잘동작하는데 내가 만든 쉘에는 잘동작하는 경우도 있고 아닌 경우도 있따.

왜 그럴까????

 

 

+ Recent posts