내가 공부한후 후에도 참고할겸 작성하는 글 입니다.
리눅스 시스템프로그래밍 2판을 참고하였습니다. 참고로 저는 WSL2 환경에서 공부중 입니다.
1 exec 함수란 무엇인가?
간단히 새로운 process가 실행되는 것 이다. 기존에 실행되고 있던 process의 내용을 대체한다음 program counter를 초기화후 다시 main함수의 첫부분부터 새롭게 읽어들인다.
새로운 프로그램의 실행(executing)이라 하며 이 기능은 exec류 시스템 콜에서 제공한다.
2 함수의 정의
▶ 우선 함수의 prototype을 알아본후 하나씩 설명해 나가겠다.
- path에는 원하는 실행가능한 파일의 경로를 적어주면 된다.
- arg0 에는 실행가능한 파일의 이름을 적어주거나 or path에 적었던 경로를 그대로 적어주어야 한다.
- ... 에는 arg1, arg2, ...으로 인자값의 갯수에는 제한이 없다.
- 가변인자 목록의 마지막은 꼭 NULL(0)으로 끝나야 한다. 이는 가상주소공간에서의 주소 0을 의미한다.
- return값은 없으며, 오류가 발생할 경우에만 -1을 return해준다.
execl의 호출 성공시 프로세스의 가상주소공간과 프로세스 뿐만 아니라, 다른 속성들도 변하게 된다.
- 대기중인 시그널은 사라진다
- 프로세스가 받은 시그널은 default방식으로 처리된다.
- 스레드 속성또한 기본값으로 돌아간다.
- 메모리에 mapping된 파일을 포함하여 그 process의 메모리 주소공간과 관련된 모든 내용이 사라진다.
기존의 pid값을 알고있는 파일이 있다면 열었던 모든 파일에접근이 가능하다. 하지만 이런방식은 바람직하지 않을수 있어서 실제사용할때는 exec를 호출하기전에 파일을 모두 close()한다.
아직 이렇게만 보고는 이해가 가지 않을 수 있다. 다음 예시를 보면 조금더 명확해 질 것이다.
3 예시
▶ 다음은 기존의 실행중이던 process를 /bin/vi로 바꾸는 코드이다.
이를 그림으로 확인해 보면 조금더 명확해 질 것이다. 다음그림을 확인해 보자.
이렇게 될 경우 process의 숫자는 증가하지 않았지만 새로운 프로그램이 실행 된 것이다.
그림이 꼭 두개의 process가 생성된것 처럼 보이는대 오해하지 말아달라 하나의 process 메모리 공간에서 일어나는 것 이다.
BUT!!
이렇게 기존의 process을 멈춘후 완전 새로운 process를 실행시키기 보다는 기존의 부모 process는 그대로 두고, 따로 child process에서 execl을 이용하여 새로운 프로그램을 실행하는것이 일반적이다. 다음 코드를 확인해 보자.
눈썰미가 좋은 사람이라면 위의 코드를 본 후에 한가지 의문이 들수도 있다.
if문에서 child를 형성한후 왜 else문으로 parent부분의 코드를 만들지 않은것 이지? 란 생각이 들수도 있다.
여기서 중요한것이 child에서는 execl은 ret = execl( ~ )이후의 코드는 실행되지 않는다는 것 이다.
즉 fork된 후 child가 형성되었는대 child에서 execl을 실행하였기에 child는 완전히 새로운 process로 바뀌었다.
따라서 fork후 if문의 조건에 해당하지 않는 나머지 부분이 자동적으로 parent가 되는 것 이다.
4 끝으로
나도 아직 배울점이 많고 계속 시스템프로그래밍을 공부중이다. 이것과 병행하여 열혈C 자료구조도 공부중인대 linked list 내용이 아주 재미있고 흥미롭다. C언어가 은근 재미있는 구석이 많은 언어인것 같다. fork와 signal, Thread 등 여러부분을 읽었는대 추후 더 공부하여 글을 하나씩 써나가겠다.
'CS > System Programming (2021-2)' 카테고리의 다른 글
[시스템 프로그래밍] wait 함수 (0) | 2022.01.19 |
---|---|
[시스템 프로그래밍] Zombie Process : 좀비 프로세스 (0) | 2022.01.19 |
[시스템 프로그래밍] fork 함수 (0) | 2022.01.19 |
[시스템 프로그래밍] Process : 프로세스 (0) | 2022.01.19 |
Vim 에디터 사용법 (vi 에디터) (0) | 2022.01.18 |
댓글