[ 시스템 프로그래밍 ] fork()와 execve()의 차이를 알아보자

sangjun

·

2022. 4. 14. 18:56

http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

1. fork()란 무엇인가

 - 새로운 프로세스를 생성한 뒤에 현재 프로세스의 메모리 상태를 새로운 프로세스에 그대로 복사하는 것이다.

 - 부모 프로세스의 메모리 상태에서 몇 가지를 제외하고 그대로 복사하는데 이 중에 부모 프로세스와 다른 것은 pid이다. 

 - 아래 결과를 보면 부모 프로세스와 자식프로세스는 독립된 메모리 주소를 사용한다. ( Code 영역은 공유함 )

 - 아래 출력 결과를 보면 자식 프로세스에서 printf를 찍어도 stdout으로 출력된다. 즉, 부모 프로세스의 파일 디스크럽터를 자식프로세스에서 복사한다.

 - fork로 만들어진 자식 프로세스 <--> 부모 프로세스 사이의 통신은 IPC통신을 한다. 대표적으로는 PIPE통신이 있다.

 - return값은 2개이고, 0과 프로세스 id이다. 0은 자식 프로세스가 갖고 프로세스 id는 부모가 갖는다.

#include <sys/types.h>
#include <stdio.h>

int a=0x1337;
int main(){
    int b=0xdeadbeef;

    int status;
    pid_t pid;

    printf("fork test\n");

    pid=fork();
    printf("pid is %d %d\n",pid,getpid());

    if(pid==0){
        a+=1;b+=1;
        printf("this is child process a: %p b: %p\n",a,b);
    }
    else{
        wait(&status);
        printf("this is parent process a: %p b: %p\n",a,b);
    }
}

 

 

2. execve()는 무엇인가

 - 실행가능한 파일을 현재 프로세스에 적재하여 새로운 기능을 실행하는 것

 - exec계열의 함수는 execl, execlp, execle, execv, execvp, execvpe가 있으면 모두 다 최종적으로는 execve를 호출하는 wrapping함수이다.

l : argument가 list형태로 받는다는 뜻
v : argument가 배열형태로 받는다는 뜻
p : 첫번째 파라미터가 PATH경로에 존재한다면 상대경로나 절대경로를 주지 않아도 된다는 뜻
e : 환경변수를 인자로 받을 수 있다는 뜻
//gcc -o execve execve.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(){
    char *argv[]={
        "ssu_execl_test_1",
        "param1",
        "param2",
        (char *)0
    };

    char *env[]={
        "Name=sangjun",
        "nextname=nextsangjun",
        "HOME=/home/nonpriv",
        (char*)0
    };

    printf("this is the original program\n");
    execve("./ssu_execl_test_1",argv,env);
    printf("%s\n","This line shoud never get printed\n");
    exit(0);
}
//gcc -o ssu_execl_test_1 ssu_execl_test_1.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[]){
    extern char **environ;
    char **str;

    int i;

    for(i=0;i<argc;i++)
        printf("argv[%d]: %s\n",i,argv[i]);
    
    for(str=environ;*str!=0;str++)
        printf("%s\n",*str);

    exit(0);
}