프로그램 | 프로세스 | 스레드
- 프로그램: 바이너리, 코드 이미지, 응용 프로그램, Application, 실행 파일
- 프로세스: 메모리에(로드 및 프로세스 상태 정보 포함"PCB") 실행 중인 프로그램
- 스레드: 리눅스에서는 프로세스가 생성되면 스레드도 생성이 되며 보통 기본 프로세스(싱글 스레드 프로세스)이며 다중 스레드(멀티 스레드 프로세스)를 사용할 수도 있습니다.
각 프로세스는 고유한 pid를 가지게 되며 최대 값은 2^15 = 32768
이고 부호형(signed) 16비트 정수값을 사용합니다.
#include <sys/types.h>
#include <unistd.h>
pid_t getpid (void);
pid_t getppid (void);
프로세스의 5가지 구조
CODE, DATA, BSS, HEAP, STACK
헤더 파일: <unistd.h> 함수 원형: pid_t fork(void);
- pid = fork()가 실행되면 부모 프로세스와 동일한 자식 프로세스가 별도 메모리 공간에 생성
- 자식 프로세스는 pid가 0으로 리턴, 부모 프로세스는 실제 pid 리턴
- 두 프로세스의 변수 및 PC(Program Counter) 값은 동일
- 새로운 프로세스 공간을 별도로 만들고, fork() 시스템 콜을 호출한 프로세스(부모) 공간을 모두 복사한 후, fork() 시스템 콜 이후 코드부터 실행
헤더 파일: <unistd.h> 함수 원형 int execl (const char *path, const char *arg, ...); int execlp (const char *file, const char *arg, ...); int execle (const char *path, const char *arg, ..., char * const envp[]); int execv (const char *path, char *const argv[]); int exevp (const char *file, char *const argv[]); int exevpe (const char *file, char *const argv[], char *const envp[]);
- wait() 함수를 사용하면, fork() 함수 호출시, 자식 프로세스가 종료할 때까지, 부모 프로세스가 기다린다.
- 자식 프로세스와 부모 프로세스의 동기화, 부모 프로세스가 자식 프로세스보다 먼저 죽는 경우를 막기 위해 사용(고아 or 좀비 프로세스)
- fork()는 새로운 프로세스 공간 생성 후, 기존 프로세스의 공간을 복사한다.
즉, 4GB를 복사한다면 프로세스 생성 시간이 오래걸린다.
자식 프로세스 생성시, 부모 프로세스 페이지를 우선 사용
부모 혹은 자식 프로세스가 해당 페이지를 읽기가 아닌, 쓰기를 할 때 페이지를 복사하고, 분리함
덕분에 프로세스 생성 시간을 줄일 수 있고 새로 생성된 프로세스에 새롭게 할당되어야 하는 페이지 수도 최소화할 수 있다.
프로세스 종료 시스템 콜
부모 프로세스는 status & 0377 계산 값으로 자식 프로세스 종료 상태 확인 가능#include <stdlib.h> void exit(int status);
atexit() 함수
프로세스 종료시 실행될 함수를 등록하기 위해 사용
등록된 함수를 등록된 역순서대로 실행
main() 함수에서 return 0; 은 exit() 호출과 큰 차이가 없다.