여기서 의문점이 생긴다
- psh1으로 충분한걸까?
- 명령이 실행된 즉시 종료되어버린다
- 새로운 명령을 바로 받을수는 없을까?
- 다시 쉘을 시행해야하는 불편함이 있다
- 물론, 가장 간단하게는....
- 새 프로세스를 시행한다
- 새로운 프로세스가 프로그램을 실행하게 한다- 얼마나 많은 프로그램이 실행하고 싶은지와 관계없이,
프로그램의 수 만큼, 프로세스를 생성하면 그만~
fork |
---|
PURPOSE 프로세스를 생성한다 |
INCLUDE #include <unistd.h> |
USAGE pid_t result = fork(void) |
ARGS 없음 |
RETURNS -1: if error, 0: child process인 경우, pid: parent process인 경우 child의 pid |
그럼 간단한 포크를 알아보자
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
int ret_from_fork, mypid; //int형 변수 ret_from_fork, mypid
mypid = getpid(); //getpid함수를 사용해서 mypid
printf("Before: my pid is %d\n", mypid); // 가져온 pid를 출력, 현재 프로세스 id 확인
ret_from_fork = fork(); // fork함수를 호출해서 ret_from_fork에
// 현재 프로세스를 복제한다
sleep(1); //프로세스 실행을 1초동안 일시 중단
printf("After: my pid is %d, fork() said %d\n", getpid(), ret_from_fork);
// 이게 뭘 출력하는걸까?
// getpid(): 현재 프로세스의 id값
// ret_from_fork: fork()함수의 반환값, 즉 자식프로세스의 ID혹은 0을 출력한다
}
간단한 fork 함수에 대한 이해를 위한 예제이다.
한번 실행화면도 확인해볼까?
다음과 같이 실행됨을 확인할수 있다.
- 현재 프로세스의 id는 3806
- fork가 진행된 후, 즉 자식프로세스의 id는 3807
- 이후 자식프로세스가 시행되며 현재 프로세스의 id는 3807, 현재 실행중인 프로세스의 id는 0으로 출력됨
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
printf("my pid is %d\n", getpid()); //현재 프로세스의 id출력
//첫번째 fork함수 호출
fork(); // 현재 프로세스는 복제, 부모와 자식 프로세스가 생성.
// 다음 줄로 진행, 자식프로세스도 다음줄로 진행
// 두번째 fork 호출
fork(); // 각각 부모와 자식 프로세스는 다시 복제됨
// 2^2승, 즉 4개의 프로세스 생성
// 생성된 프로세스들이 다음 줄로 진행됨
// 세번째 fork 호출
fork(); // 각 부모 프로세스와 자식프로세스는 다시 복제
// 2^3, 즉 8개의 프로세스 생성
printf("my pid is %d\n", getpid()); //각 프로세스의 id출력
}
코드만 보면 무슨소리인지 이해하기가 힘들것이다
그림과 함께 봐보자
이와 같이, fork함수가 처음 실행되면 부모프로세스(1), 과 자식프로세스(1)이 생성된다
fork함수가 두번째로 실행되면 각 부모프로세스(1), 자식프로세스(1)의 자식프로세스들이 생성됨,
그러므로 자식 프로세스들이 2개가 생김
.
.
.
이렇게 계속 반복해서 3번!
실행화면으로도 확인해보자!
총 출력하는 프로세스의 id 개수를 살펴보자
총 9개! 부모프로세스 1개와 fork로 인해 생성된 자식프로세스 8개로 총 9개가 된다!
이 코드 또한, fork의 실행방식을 보여준다!
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
int fork_rv; //fork_rv라는 int형 변수 선언
printf("Before: my pid is %d\n", getpid()); // 현재 실행중인 프로세스의 id를 가져옴
fork_rv = fork(); //fork를 통해서 fork_rv에 id값 저장
if(fork_rv == -1) //만약! fork_rv값이 -1이라면, 즉 fork를 하는데에 오류가 생긴다면
perror("fork"); //'fork'라는 에러 메세지를 출력
else if(fork_rv == 0) //만약! fork_rv값이 0이라면 child process라는것을 의미한다!
printf("I am the child. my pid = %d\n", getpid()); // 그러므로 값을 출력
else //나머지 경우에는?
printf("I am the parent. my child is %d\n", fork_rv); //parent값이 출력된다
}
자, 이것도 fork를 이해하기위한 예제이다
실행 화면을 먼저 봐볼까?
- 보다시피, 현재 실행중인 프로세스의 id값을 먼저 출력하게된다
- 현재 id값을 출력
- 현재 프로세스 id값 출력
자, 슬슬 세가지 예제 코드를 보면서 헷갈릴것이다
fork함수에 대해 다시 복기해보자
이 점들을 다시 확인하면서 예제 코드를 보면 더 도움 될것이다
우리는 쉘을 만들기 위한 요소들에 대해 확인하고 있다.
마지막으로 쉘을 만들었을때는
이 링크의 방법을 통해 프로그램을 실행시키기만 하는 쉘을 만들었었다!
이번 포스트에서 fork함수를 통해 새로운 프로세스를 만들 수 있게 되었다.
새로운 프로세스 만들기
- fork()
프로그램을 실행하는법
- execvp()
부모 프로세스가 자식 프로세스가 특정 명령을 실행하는동안 기다리게 하는 방법
- wait()
wait 함수를 추가해서 좀 더 완벽한 셀을 만들어보자!!