프로세스
Process ID
real UID
effective UID
real GID
effective GID
부모 프로세스
자식 프로세스
좀비 프로세스
exit()
를 호출하면서 종료되면 이 프로세스에 관련된 모든 메모리와 자원이 해제되어 다른 프로세스에서 사용할 수 있다.wait()
을 통하여 좀비는 제거된다.고아 프로세스
wait()
함수를 호출하여 고아 프로세스의 종료 상태를 회수함으로써 좀비가 되는 것을 방지한다.wait()
하는 것이 좋다.)멀티 프로세스의 특징
fork()와 exec()의 차이
fork()
새로운 프로세스를 위한 메모리를 할당한다. (프로세스가 하나 더 생기는 것)exec()
는 fork()처럼 새로운 프로세스를 위한 메모리를 할당하지 않고, exec()를 호출한 프로세스가 아닌, exec()에 의해 호출된 프로세스만 메모리에 남는다.exec()와 system()의 차이
char buf[255];
sprintf(buf, "grep -n %s %s", search, path);
system(buf);
printf("system함수가 실행되었습니다.\n"); //실행됨
execl("/bin/grep", "grep", "-n", search, path, NULL);
printf("exec함수가 실행되었습니다.\n"); //실행되지 않음
함수 원형.
pid_t fork(void)
기능. 새 프로세스를 생성한다.
헤더.<unistd.h>
리턴값1. 부모 프로세스에서는자식 프로세스의 PID
를 반환받는다.
리턴값2. 자식 프로세스에서는0
을 반환받는다.
리턴값3.-1
errno
- fork() 함수를 호출하는 프로세스는 부모 프로세스가 되고, 생성된 프로세스가 자식이 된다.
- 생성된 자식 프로세스는 부모 프로세스의 내용을 그대로 복사하여 가진다.
- fork 함수 호출 이후 코드부터 각자의 메모리를 사용하여 실행된다.
함수 원형.
pid_t wait(int *status)
기능. 부모가 자식이 종료했음을 확인한다.
하위 프로세스가 끝날 때까지 현재 프로세스의 실행을 잠시 정지한다. 종료 상태 값을 의식하지 않으면 매개변수 status를 NULL로 설정할 수 있다.
헤더.<wait.h>
매개변수.int *status
리턴값1.pid_t
PID
리턴값2.-1
errno
- 부모가 자식의 종료 상태를 얻기 위해 사용된다.
- 자식 프로세스가 동작 중이면 호출이 차단되기 때문에, 상태를 얻어올 때까지 대기한다.
wait()
호출자가 시그널을 받을 때까지 대기한다.- 자식 프로세스가 종료된 상태라면 즉시 호출이 반환되어 상태를 얻는다. (자식 프로세스의 PID 반환)
- 자식 프로세스가 없다면 호출이 즉시 반환되며, 에러값을 반환한다.
함수 원형.
pid_t waitpid(pid_t pid, int *status, int options)
기능. 특정 자식 프로세스의 종료를 기다릴 수 있다.
헤더.<wait.h>
매개변수1.pid_t pid
매개변수2.int *status
자식 프로세스 상태 확인가능
매개변수3.int options
리턴값1.pid_t
PID
리턴값2.-1
errno
pid_t pid
pid(자식 PID)의 값 | 디테일 |
---|---|
pid < -1 | pid의 절대값과 동일한 프로세스 그룹ID의 모든 자식 프로세스의 종료를 기다림 |
pid == -1 | 임의의 자식 프로세스의 종료를 기다림 |
pid == 0 | 현재 프로세스의 프로세스 그룹ID와 같은 프로세스 그룹ID를 가지는 모든 자식 프로세스의 종료를 기다림 |
pid > 0 | pid값에 해당하는 프로세스의 종료를 기다림 |
int *status
매크로 | 디테일 |
---|---|
WIFEXITED(status) | 0이 아닌 값을 리턴하면 자식 프로세스가 정상 종료했다는 뜻 |
WEXITSTATUS(status) | 이 매크로를 통하여 자식 프로세스가 정상 종료했음을 확인하면, 종료 코드를 확인 할 수 있음. 이 종료 코드는 exit(),_exit()에서 인자로 주는 값을 말함. 즉 exit(0)으로 프로그램을 종료했다면, 0 값이 WIFEXITED 매크로로 알 수 있음. 단, 이 매크로는 하위 8비트 값만을 확인하므로 0부터 255까지의 값까지 확인할 수 있음. |
WIFSIGNALED(status) | 이 매크로가 참이라면 자식 프로세스사 비정상 종료했다는 뜻 |
WTERMSIG(status) | WIFSIGNALED(stauts) 매크로가 참일 경우, 자식 프로세스를 종료시킨 시그널 번호를 얻는 매크로 |
WIFSTOPPED(status) | 이 매크로가 참이면, 자식 프로세스는 현재 멈춰있는 상태임. options 인자에 WUNTRACED 옵션이 설정되어 있는 경우 자식 프로세스의 멈춤 상태를 알아낼 수 있음. |
WSTOPSIG(status) | WIFSTOPPED(status)가 참이면, 자식 프로세스를 멈춤 상태로 만든 시그널 번호를 얻음 |
WCOREDUMP(status) | 시스템에 따라서는 WIFSIGNALED(status)가 참일 경우, 자식 프로세스가 core덤프 파일을 생성했는지를 확인하는 매크로를 제공해주기도 함 |
int options
option | 의미 |
---|---|
WNOHANG | waitpid()를 실행했을때, 자식 프로세스가 종료되어 있지 않으면 블록상태가 되지 않고 바로 리턴하게 해줌 |
WUNTRACE | pid에 해당하는 자식 프로세스가 멈춤 상태일 경우, 그 상태를 리턴함. 즉, 프로세스의 종료 뿐만 아니라 멈춤 상태도 찾아냄 |
함수 원형.
int execl(const char *path, const char *arg0, .., const char *argn, /* (char *)NULL */)
기능. exec + l (인자의 목록 list)
fork를 통해 새로운 프로세스를 생성했다면, 실행되는 중에 다른 형태의 프로세스로 변하고 싶을 때 사용한다.
현재 실행중인 메모리를 비우고 처음부터 다시 시작하게 해준다.
path 경로명의 파일을 실행하며, arg0~argn을 인자로 전달한다.
관례적으로 arg0에는 실행 파일명을 지정하고, 마지막 인자로는 끝을 의미하는 NULL을 지정해야한다.
헤더.<unistd.h>
매개변수1.const char *path
매개변수2~n.const char *arg0~*argn
매개변수z.NULL
리턴값.int
에러가 있을 때만-1
을 리턴한다.
함수 원형.
int execle(const char *path, const char *arg0, .., const char *argn, /* (char *)NULL, char *const envp[] */)
기능. exec + l (인자의 목록 list) + e(환경변수 전달가능 environment)
실행가능한 파일인 path의 실행코드를 현재 프로세스에 적재하여 기존의 실행코드와 교체하여 새로운 기능으로 실행한다. 즉, 현재 실행되는 프로그램의 기능은 없어지고 path 프로그램을 메모리에 loading하여 처음부터 실행한다.
헤더.<unistd.h>
매개변수1.const char *path
명령어가 위치한 절대 path 또는 상대 path를 포함한 명령어 (ex. /usr/bin/ls)
매개변수2~n.const char *arg0~*argn
명령어 다음에 오는 파라미터를 순서대로 나열하며, 끝은 NULL로 끝나야 한다. (ex. ls)
매개변수z.char *const envp[]
path 명령어로 교체되면서 적용될 환경변수 (만약 현재의 환경변수를 그대로 유지하려면, environ 전역변수를 parameter로 전달하면 된다.)
리턴값1.없음
정상적으로 처리되면 execle() 다음 로직은 실행할 수 없다. 이미 다른 프로그램이 되었기 때문이다.
리턴값2.-1
binary 교체가 실패하였으며, 상세한 오류 내용은 errno에 설정된다.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
//현재의 환경변수를 그대로 유지하려면, environ 전역변수를 parameter로 전달하면 된다.
extern char **environ;
int main(int argc, char *argv[])
{
if (execle("/bin/bash", "bash", NULL, environ) == -1) {
perror("execle()");
}
/*ls 명령어 binary로 실행로직이 교체되었으므로 이후의 로직은 실행되지 않는다. */
printf("this is ls.\n");
return 0;
}
/* 환경변수 출력하는 프로그램 */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc > 1) {
printf("환경변수 %s는 %s 입니다.\n", argv[1], getenv(argv[1]));
}
else {
printf("실행방법: show_envp[환경변수]\n");
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
int main()
{
char *envp[] = { "TEST=ttttttt", NULL };
execle("./execle2_1", "./execle2_1", "TEST", NULL, envp);
printf("이 메세지가 보이면 안됨\n");
return 0;
}
함수 원형.
int execv(const char *path, char *const argv[])
기능. exec + v(인자 배열)
헤더.<unistd.h>
매개변수1.const char *path
실행 파일의 디렉토리 포함 전체 파일 명
매개변수2.char *const argv[]
인수 목록
리턴값.int
실패할 때만-1
함수 이름 | 프로그램 지정 | 명령라인 인수 | 함수 설명 |
---|---|---|---|
execl | 디렉토리와 파일 이름이 합친 전체 이름 | 인수 리스트 | 환경 설정 불가 |
execle | 디렉토리와 파일 이름이 합친 전체 이름 | 인수 리스트 | 환경 설정 가능 |
execv | 디렉토리와 파일 이름이 합친 전체 이름 | 인수 배열 | 환경 설정 불가 |
함수 원형.
int system(const char* command)
기능. 시스템 명령을 수행한다.
헤더.<stdlib.h>
매개변수.const char* command
명령어
리턴값.int
명령을 수행하여 해당 프로세스가 종료하면, 종료할 때의 값을 반환한다.
196-245