리눅스에는 execl, execlp, execle, execv, execvp, execvpe 처럼 exec 계열의 함수가 있다.
인자 전달하는거 따라서 이름이 조금씩 변한다.
https://man7.org/linux/man-pages/man3/exec.3.html
자세한건 찾아보도록하자
현재 프로세스 이미지를 인자로 준 바이너리 이미지로 대체한다.
포너블 문제를 풀 때, gdb 를 붙여서 디버깅 하는데,
system("/bin/sh") 이런걸 실행했을 때, gdb 에서 더이상 디버깅이 안되는 경우가 있는데,
system 함수 내부에서 execve 를 실행하므로 현재프로세스가 /bin/sh 로 대체되기 때문이다.
fork 함수는 이와 다르게, 새 프로세스를 복제해서 생성한다.
분리된 메모리공간을 새로 할당받지만, 생성되었을 때 메모리는 같은 내용을 담고있다.
caller : 부모
callee : 자식
근데 자식프로세스에서도 또다른 자식프로세스를 생성할 수 있다.
fork 함수 리턴값
+ 성공 : 자식 PID
+ 실패 : -1
+ fork 실행으로 생성된 자식프로세스 : 0
#include <stdio.h>
#include <unistd.h>
int main() {
int x;
x = 55;
int d=fork();
printf("PID : %ld, x : %d, d : %d\n",getpid(), x,d);
x = 100;
d=fork();
printf("PID : %ld, x : %d, d : %d\n",getpid(), x,d);
return 0;
}
자식 프로세스를 두 개 생성하는 간단한 예제입니다.
첫 번째 fork 실행으로, 자식프로세스가 생성됩니다.
자식프로세스가 생성될 때, 자식프로세스에서도 동일하게 int d = fork(); 문부터 시작합니다.
하지만, 이 부분은 자식프로세스가 생성된 부분이기때문에 fork 함수에서는 0을 반환하게 됩니다.
이 특징으로,
if(!fork()){
// 자식
}
else {
// 부모 or error
}
이렇게 부모/자식 프로세스에서 처리해야할 일을 나눌 수 있습니다.
밑에도 동일하게 처리되는데, 그림을 그려 flow 를 파악해봅시다.
부모프로세스인 949 는 950 / 951 을 생성합니다.
x=100 은 중간에 있으니, 950 을 x=55 를 복사해서 갖고, 951 은 x=100 을 복사해서 갖게됩니다.
950 에서도 fork 가 두 번 실행되어, 0 / 952 를 리턴받는데, 0 출력할 때는 x=55 를 출력하고,
x=100 설정, 952 프로세스에서는 x=100 을 복사해 갖게되고 fork 함수 한 번 실행되어 0 리턴받고 출력
951 에서는 x=100 을 복사해서 가졌고, fork 함수가 한 번 실행되어 0 리턴받고 출력
핵심은, 자식프로세스가 실행된 fork 에서는 0이 리턴되고, 다른 fork 를 만나면 또다른 자식프로세스를 생성한다는 점이다.
만약 fork 가 3 번 실행된다면 총 몇개가 생성될까요?
수학을 못해서 여기까지하겠습니다.