[Linux] fork(), wait(), exec()
- [ CS기초 ]/Linux
- 2022. 4. 17.
리눅스에는 '프로그램'과 그 프로그램이 실행되는 환경인 '프로세스'라는 개념이 있다. 제목으로 써놓은 함수들이 바로 해당 프로세스를 제어하는 함수들이다.
1. fork()
#include<unistd.h>
pid_t fork(void);
fork()는 기존 프로세스가 새 프로세스를 생성할 때 사용하는 시스템 호출 함수이다. fork()함수를 사용하여 생성한 프로세스를 자식 프로세스라고 하며, 함수가 호출된 기존 프로세스를 부모 프로세스라고 한다. fork()함수는 한번 호출되나, 호출한 프로세스에 따라 다른 값을 리턴한다. 부모 프로세스에는 새로 생성된 자식 프로세스의 ID를 리턴하고, 자식 프로세스에는 0을 리턴한다. 프로세스 생성에 실패한 경우는 -1을 리턴하고 errno값을 갱신한다.
부모 프로세스는 자식 프로세스의 pid(process id)를 직접 알아낼 수 없다. 자식프로세스는 getppid()함수를 통해서 부모 프로세스의 pid를 알아낼 수 있다. 또한 자식 프로세스는 부모 프로세스의 데이터, 힙, 스택영역의 복사본(copy on write 방식으로)을 갖기 때문에 다른 메모리 공간을 사용하지만, 코드(텍스트)영역은 자식과 부모가 공유하여 사용한다. 따라서 자식 프로세스의 데이터값 조작은 부모 프로세스와 무관하다(fork의 리턴값을 받아서 if문으로 분기하여 값을 조절할 수 있다.)
일반적으로 fork가 호출되었을 때의 프로세스간 실행 순서는 커널에 따라 다르다.
2. wait()/waitpid()
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* statloc);
pid_t waitpid(pid_t pid, int* statloc, int options);
wait()류 함수는 프로세스의 종료 상태를 회수하는 시스템 호출 함수이다. 부모 프로세스는 자식 프로세스의 종료 시점을 알 수 없기 때문에, 커널은 SIGCHILD 시그널을 통해서 부모 프로세스에게 종료 결과를 알려주고, 부모 프로세스는 handler function을 통해서 규정된 동작을 지시할 수도 있다. waitpid함수는 가장 먼저 종료되는 자식 프로세스의 정보를 리턴받는 wait함수와 달리 특정 pid를 갖는 자식 프로세스를 지정하여 정보를 출력할 수 있고, options 매개변수에 추가로 상수를 대입하여 옵션을 지정할 수 있다.
pid_t pid;
int status;
if((pid = fork())<0) {
fprintf(stderr, "fork error\n"); exit(1); //fork error 처리
}
else if (pid==0)
exit(7); //자식프로세스 종료
if(wait(&status)!=pid); {
fprintf(stderr, "wait error\n"); exit(1);
}
부모 프로세스가 wait()의 매개변수로 종료 상태를 statloc 포인터(위 코드의 status)가 가리키는 곳에 저장하고 종료된 자식 프로세스의 pid값을 리턴한다.
자식 프로세스가 어떻게 중단/종료되었는지에 따라서 statloc 인자는 다른 상태값을 가진다.
3. exec~()
#include<unistd.h>
int execl(char* pathname, char* arg0, ... , (char*)0);
int execv(char* pathname, char* argv[]);
int execle(char* pathname, char* arg0, ... , (char*)0, char* envp[]);
int execve(char* pathname, char* argv[], char* envp[]);
int execlp(char* filename, char* arg0, ... , (char*)0);
int execvp(char* filename, char* argv[]);
exec()류 함수는 현재 수행되고있는 프로세스를 대신하여 지정한 명령이나 실행 파일을 새로운 프로세스로 수행시키는 함수이다. exec 뒤에는 (l|v){(e|p)}와 같이 문자가 붙을 수 있는데, 각각 l은 명령인자를 리스트로, v는 명령인자를 벡터(배열)형태로, e는 환경변수 인자, p는 환경변수를 이용한 파일이름을 의미한다.
exec()류 함수에 넘겨준 매개변수들은 새로운 프로세스의 실행 인자 argv에 전달되고, argc에는 인자 개수가 들어간다. 함수가 성공적으로 수행된 경우, 리턴하지 않고 새로운 프로세스의 main()이 실행된다.
'[ CS기초 ] > Linux' 카테고리의 다른 글
[Linux] C 표준 입출력 라이브러리 함수(2) (0) | 2022.04.14 |
---|---|
[Linux] 파일 입출력 System call 함수 (0) | 2022.03.14 |
[Linux] C 표준 입출력 라이브러리 함수 (1) (0) | 2022.03.13 |