리눅스에서 프로세스process는 사용자가 명령행에서 직접 프로그램을 실행해 생성하는 경우도 있지만, 프로그램 안에서 프로그램을 실행해 생성하는 경우도 있다. 이렇게 프로그램 안에서 다른 프로그램을 실행해 새로운 프로세스를 생성할 때는 system(), fork(), vfork()함수를 사용한다.
프로세스 생성 함수
fork()함수로 자식 프로세스를 생성하면 부모 프로세스와 자식 프로세스는 순서에 관계없이 실행되고, 먼저 실행을 마친 프로세스는 종료된다. 이때 좀비 프로세스zombie process같은 불안정 상태의 프로세스가 발생한다. 이를 방지하려면 아래 표의 함수를 사용해 부모 프로세스와 자식 프로세스를 동기화 해야 한다.
프로세스 동기화 함수
system() 함수는 프로그램 안에서 새로운 프로그램을 실행시키는 사장 간단한 방법이다. 그러나 명령을 실행하기 위해 셸까지 동작시키므로 비효율 적이다. 따라서 system() 함수를 남용하는 것은 바람직하지 않다.
system() 함수는 기존 명령이나 실행 파일명을 인자로 받아 셸에 전달한다. 셸은 내부적으로 새 프로세스를 생성해 인자로 받은 명령을 실행하고, 해당 명령의 실행이 끝날 때까지 기다렸다가 종료 상태를 return한다.
리눅스에서 프로세스를 생성해 프로그램을 실행하는 대표적인 방법은 fork() 함수를 사용하는 것이다. fork() 함수는 부모 프로세스를 거의 그대로 복제해 새로운 프로세스를 생성한다.
fork() 함수가 생성한 새로운 프로세스를 자식 프로세스 child process라고 한다.
fork() 함수를 호출한 프로세스는 부모 프로세스parent process가 된다. fork() 함수가 리턴하면 부모 프로세스와 자식 프로세스가 동시에 동작하는데, 어느 프로세스가 먼저 시행될지는 알 수 없다. 처리 순서는 시스템의 스케쥴링scheduling에 따라 달라진다.
vfork() 함수도 fork() 함수처럼 새로운 프로세스를 생성하지만 부모 프로세스의 메모리 공간을 모두 복사하지는 않는다. vfork() 함수로 생성한 자식 프로세스는 exec함수군을 사용해 새로운 작업을 수행할 때 효율적이다. 그러나 vfork()함수는 버그가 발생할 우려도 있어 리눅스에서 제공은 하지만 사용을 추천하지는 않는다.
fork()함수로 자식 프로세스를 생성하면 부모 프로세스와 자식 프로세스는 순서에 관계없이 실행되고, 먼저 실행을 마친 프로세스는 종료한다. 그런데 부코 프로세스와 자식 프로세스 사이의 종료 절차가 제대로 진행되지 않을 때가 있다. 이때 좀비 프로세스zombie process 같은 불안정 상태의 프로세스가 발생하는데, 이를 방지하려면 부모 프로세스와 자식 프로세스를 동기화해야 한다.
실행을 종료한 후 자원을 반납한 자식 프로세스의 종료 상태 정보를 부모 프로세스가 받지 않는 경우에는 좀비 프로세스가 발생한다. 좀비 프로세스는 프로세스 테이블에만 존재한다. 좀비 프로세스는 일반적인 방법으로 제거할 수 없으며, 부모 프로세스가 wait() 함수를 호출해야 사라진다.
만일 자식 프로세스보다 부모 프로세스가 먼저 종료되면 자식 프로세스는 고아 프로세스가 된다. 고아 프로세스는 init(PID 1) 프로세스의 자식 프로세스로 등록된다.
부모 프로세스와 자식 프로세스를 동기화하려면 부모 프로세스는 자식 프로세스가 종료될 때 까지 기다려야 한다. 자식 프로세스의 실행이 완전히 끝나기를 기다렸다가 종료 상태를 확인하는 함수는 wait(), waitpid()다.
wait() 함수는 자식 프로세스가 종료할 때 까지 부모 프로세스를 기다리게 한다. 자식 프로세스의 종료 상태는 wstatus에 지정한 주소에 저장된다. 만약 부모 프로세스가 wait() 함수를 호출하기 전에 자식 프로세스가 종료되면 wait() 함수는 즉시 리턴한다. wait() 함수의 리턴값은 자식 프로세스의 PID다. wait() 함수의 리턴값이 -1이면 살아있는 자식 프로세스가 하나도 없다는 의미다.
wiat() 함수는 자식 프로세스가 여러 개일 경우 아무 자식 프로세스나 종료하면 리턴하지만 waitpid() 함수는 특정 PID의 자식 프로세스가 종료하기를 기다린다. waitpid() 함수는 pid로 지정한 자식 프로세스가 종료하기를 기다리며, 자식 프로세스의 종료 상탯값을 status에 저장하고 options의 조건에 따라 리턴한다.
idtype : 종료를 기다리는 자식 프로세스 유형 정의
id : 식별 번호
infop : siginfo_t 구조체 포인터
options : waitid() 함수의 리턴 조건
waitid() 함수는 OPSIX 표준으로 리눅스에서 제공한다. 유닉스 시스템에서는 제공하지 않을 수도 있다. waitid() 함수는 waitpid() 함수와 마찬가지로 특정 자식 프로세스가 종료하기를 기다리게 할 수 있다. waitid() 함수가 기다리는 자식 프로세스의 PID만 인자로 지정하는 것과 달리 waitid() 함수는 좀 더 세부적으로 덩의할 수 있다.