1. 새로운 메모리 공간 할당
2. 1의 공간에 프로세스 로딩 및 콜 스택 생성
3. 해당 PCB 초기화
4. 준비큐에 프로세스 넣기(실행 가능)
다른 프로세스를 생성하는 프로세스를 부모 프로세스(Parent Process)라 하고, 다른 프로세스에 의해 생성된 프로세스를 자식 프로세스(Child Process)라 한다. 프로세스의 부모-자식 관계들은 트리의 형태로 나타나게 된다.
대부분의 운영체제에서는 프로세스들을 구별하기 위해 각 프로세스들에게 유일성을 가진 정수 PID(Process Identifier)를 부여한다.
일반적으로, 프로세스는 CPU time, 메모리, 파일, 입출력 장치 등의 자원이 필요하다. 따라서 어떤 프로세스가 다른 프로세스를 하나 생성하면, 생성된 프로세스는 운영체제로부터 직접 자원을 제공받거나 부모 프로세스 자원의 일부를 한정적으로 사용할 수도 있다.
프로세스 생성
fork()
- 현재 프로세스에서 새 프로세스 하나를 생성한다.
- 생성된 프로세스는 부모 프로세스와 동일한 address space를 가진다. 이는 부모 프로세스와 자식 프로세스가 수월하게 통신(communicate)할 수 있도록 해준다.
- 부모, 자식 프로세스 모두 fork() 호출 이후 실행을 계속하지만, 자식 프로세스는 0을 반환하고 부모 프로세스는 non-zero 값을 반환한다.
- 자식 프로세스는 부모 프로세스의 fork() 호출 이후 내용부터 실행된다.
프로세스 생성 속도를 높이기 위한 - copy on write
프로세스 정보는 memory에서 OS가 관리하기 편한 상태인 페이지 단위로 저장되는데,
프로세스가 fork되면 부모 프로세스의 페이지로 들어가 굳이 페이지를 하나 더 생성하지 않는다.
하지만 자식프로세스에서 부모프로세스의 데이터를 읽거나 참조하는게 아닌(read)
새로운 데이터를 생성하거나 수정하면(write) 부모 프로세스의 페이지를 복사해서 새로운 페이지를 만든다.
프로세스 실행
exec()
Linux/UNIX 환경에서 프로세스를 새로운 프로그램을 실행하는 프로세스로 대체하는 시스템 콜 함수입니다.
생성된 프로세스를 실행하는 함수
- fork()와 다르게 자식 자식 프로세스를 생성하는 것이 아닌 현재 프로세스의 프로그램 코드를 새로운 프로그램 코드로 바꿔줍니다. 이로 인하여 프로그램 코드, 메모리, 파일 등 프로세스 자원이 새로 바뀌게 됩니다.
- exec() 함수는 현재 프로세스가 완전히 새로운 프로그램을 실행하는 프로세스로 대체되므로 반환 값이 없습니다.
메모리에서 실행되는 프로세스가 부모에서 자식으로 바뀜
wait()
- pid_t wait(int *statloc) 형태이며 자식 프로세스가 종료될 때까지 현재 프로세스의 동작을 멈추는 시스템 콜 함수입니다.
- 자식 프로세스가 종료되면 자식 프로세스 종료 시그널(SIGSHLD)이 발생하여 waiting queue에 있는 부모 프로세스가 ready queue로 넘어가게 되어 다시 실행이 가능해집니다.
- 블럭 모드로 동작하기 대문에 비용이 비싸며 자식 프로세스 관리를 하지 않으면 무한정 대기, 혹은 함수가 OS에 의해 강제 종료당할 수 있습니다.
- 종료된 자식 프로세스의 PID를 반환하며 인자로 받은 statloc에 프로세스의 종료 상태를 알 수 있는 번호가 입력됩니다
프로세스 종료
자발적 종료
exit()
현재 프로세스가 종료되어 SIGCHLD 시그널이 부모 프로세스로 전달되고, wait() 된 부모 프로세스는 자식 프로세스의 exit() 함수에 의해 정상 종료가 됨을 알 수 있습니다.
- void exit(int status) 형태입니다.
- status 값이 부모 프로세스 wait(int *statloc)의 statloc에 지정되어 반환합니다. 이를 통해 부모 프로세스는 자식 프로세스가 정상 종료 혹은 문제가 있었는지 확인할 수 있습니다.
- 함수 호출 후 자식 프로세스에 할당된 모든 자원은 풀어집니다.
- exit 함수가 없더라도 프로그램 코드의 끝에 도달하거나 return 키워드를 만나게 되면 자동으로 exit() 함수가 호출됩니다.
다시 메인문으로 돌아감, wait함수에 리턴이 돌아왔을 때
비자발적 종료
자원을 잘못 사용하고 있을 때, 자식프로세스의 실행이 불필요할 때
kill() 함수가 실행됨
생성 - 소멸
자식 프로세스를 fork 후에 나중에 실행할 거라면 wait를 바로 안써주고 나중에 자식 프로세스를 사용할 위치에서 wait하면 된다
좀비 프로세스
프로세스가 종료되고 더이상 실행할 수 없는 상태에 있을 때 커널에서 바로 PCB 같은 일부 프로세스 데이터를 제거하지 않고 애매하게 남아있는 상태
부모 프로세스에선 자식 프로세스의 종료 상태값( return 0, exit(0) )을 받아야 하는데
자식프로세스에서 exec을 했을 때 그 종료 상태 값이 부모 프로세세의 wait() 함수의 인자로 넘어오기 전까지의 자식프로세스의 상태를 좀비 상태라고 한다.
또한 자식프로세스가 끝나기 전에 부모프로세스가 끝나면 unix OS에선 init이라는 맨 처음 할당된 최상위 부모 프로세스 밑으로 붙게 된다.
'CS > OS' 카테고리의 다른 글
멀티프로세서 스케쥴링 (0) | 2022.05.02 |
---|---|
process scheduling(프로세스 스케쥴링) - FIFO, SPN, Round Robin, SRT (0) | 2022.04.09 |
Process model - 프로세스 전환(process switch) (0) | 2022.04.05 |
프로세스 - Stack Memory, PCB (0) | 2022.04.05 |
OS - system call (0) | 2022.04.05 |