시스템 프로그래밍을 배우다 보면, OS에게 직접 명령을 내리는 systemcall 함수들을 배우게 된다.
현재 process ID를 얻는 함수
pid_t getpid(void) pid_t라는 PID를 받는 리턴 타입(unsigned int)
현재 process의 PID를 리턴
pid_t getpid(void) : 부모 PID를 리턴 받음+gid_t getegid(void) , gid_t getgid(void) , uid_t geteuid(void) , uid_t getuid(void) 사용자 ID 혹은 group ID를 리턴 하는 함수 (잘 모름)
#include <unistd.h>
프로세스를 만드는 함수
현재 프로세스와 같은 코드를 가진 자식 프로세스를 생성하여 실행함
pid_t fork(void)
현재 프로세스가 자식 프로세스라면 0리턴
현재 프로세스가 부모 프로세스라면 자식 프로세스의 PID 리턴
fork()를 사용하여 process를 생성하면 생성된 자식 process는 생성시킨 부모 프로세스의 코드를 그대로 가져온다.
따라서 fork() 앞부분의 코드와 실행 내역은 일치하고, fork() 이후 코드 부터 각자의 process가 진행되게 된다.

이때 fork()가 쓰인 줄부터 차이가 발생되는데, 생성시킨 원래 부모 process는 fork()에서 자식 process PID를 리턴 받게되고, 새롭게 생성된 자식 process는 0을 리턴 받게된다.
이 점을 이용하여 자식 process가 다른 코드로 작동되게 코딩 할 수 있다.
새로 생성된 자식 process는 거의 모든 것을 부모 process로 부터 물려받지만, 물려 받지 않는 것들도 있다.(물려 받으면 이상한 것들)
1. process ID
: 당연히 다른 process이기 때문에 다른 PID를 갖는다.
2. CPU usage
: fork()로 생성된 process의 CPU 누적 사용량 정보는 0이다.
3. Locks and alarm
: 공유 resouce 권한이나 alarm timer는 각자 따로 적용된다.
4. Pending signals
: signal mask에 의해 막히는 signal은 parent process와 다르게 적용된다.
자식 process가 부모 process의 정보를 가져와 만들어 지기 때문에 데이터를 공유함에 있어 IPC(프로세스 간 통신Inter-Process Communication) 같은 복잡한 기법을 사용할 필요가 없어진다.
#include <sys/types.h>
#include <unistd.h>
자식 process가 종료되었는지 확인하는(기다리는) 함수
원래 fork()를 해도 process가 멈추는게 아니기 때문에 생성된 process가 종료되기전에 parent process가 종료되기도 한다.
때문에 wait()를 사용해 process간의 순서를 조절해야한다.
pid_t wait(int *stat_loc)
아무 자식 process 하나가 종료될때까지 기다리는 함수
*stat_loc으로 return을 받을 수 있음(상태 정보, error여부, return값 등)
pid_t waitpid(pid_t pid,int *stat_loc, int option)
더 범용적인 함수
pid_t pid parameter로 기다릴 자식 process의 PID를 지정해 기다 릴수 있다.
int option parameter로 여러 옵션을 줄 수 있음
WNOHANG 옵션은 wait()를 사용해도 non-blocking하게 작동되게함. process가 완료되지 않아도 곧바로 return. 주로 종료되었는지 확인하기 위해 사용된다.wait 류 함수의 parameter로 process의 return을 받기 위한 변수
자식 process의 exit(n), return(n)등의 parameter(n)가 넘어가게됨
단, n은 int의 하위 8bit까지만 가능
나머지는 다른 정보 전달
이런 정보들이 bit에 별로 저장되어있는데 따로 분리하기는 귀찮으니 macro로 제공됨
WIFEXITED(int* stat_val)
: 정상 종료시 0이 아님
WEXITSTATUS(int* stat_val)
: 하위 8bit인 return값(exit값) 리턴(정상종료 되었다면)
이 두개를 제일 많이 사용
WIFSIGNALED(int* stat_val)
: signal에 의해 종료되면 0이 아닌 값 반환
WTERMSIG(int* stat_val)
: signal number를 리턴함
WIFSTOPPED(int* stat_val)
: child가 정지되어있으면 0이 아닌 값 반환
WSTOPSIG(int* stat_val)
: 만약 정지되어 있다면 signal number을 반환
#include <sys/wait.h>
exec류의 함수를 쓰면 현재 코드 대신에 parameter로 넘긴 파일의 코드가 대신 실행된다.
fork()와 함께 많이 쓰인다.
main함수 부터)exec~()밑의 코드는 실행하지 않는다.(덮어써지는 것이기 때문에 실행되지 못한다)fork()후 exec()하면 완전히 새로운 코드를 자식 process로 생성할 수 있다.*arg parameter를 통해 값을 전달해 함수 실행이 가능하다.(원래 새로운 프로그램을 shell에서 실행 할때 처럼)exec() 함수는 정상적으로 작동되면 절대 return 될 일이 없다.exec() 함수 밑의 코드들도 실행 될 일이 없다.(정상적으로 실행된다면)int execl(const char \*path, const char \*arg0, ... , const char \*argn, (char\*) 0);
int execv(const char \*path, char \*const argv[]);
path : 실행할 코드의 경로명( 절대 경로 혹은 상대 경로)
arg0~argn : 입력 받을 argument들. main의 parameter이다. string의 형태로 나열
arg0은 실행파일의 이름이 될 것이다argv[] : main 함수의 argv와 같은 형식. array로 한번에 넘김.(main함수 argv 바로 써도 무방)
0 : argument의 개수가 정해지지 않았기 때문에 끝을 알리는 문자
int execle(const char *path, const char *arg0, ..,const char *argn, (char*)0, char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[],char *const envp[]);
"file" : 경로명 대신 그냥 파일이름(PATH 환경변수에 설정되어 있다면)
"envp[]" : 환경변수 추가 parameter
#include <unistd.h>
프로그램(프로세스) 종료 함수
void exit(int status)
status에 에러 관련 내용을 담아 넘기면, 호출한 process에서 오류 내용 파악 가능
프로그램(프로세스) 종료시 자동으로 실행할 함수 등록
atexit(void *func(void))
//실행되는 함수 순서
void a(){}
void b(){}
void c(){}
atexit(a);
atexit(b);
atexit(c);
exit();
c( ) -> b( ) -> a( ) 실행됨
#include <stdlib.h>
Daemon을 구현하기 위한 함수 background 일종
process를 parant process로 부터 독립 시켜줌
이때 shell process로 부터로도 독립해 input interrupt를 받지 않는 background process가 됨
잠깐 정지하는 함수
sleep(int seconds) : parameter 초 만큼 정지