[ 시스템 프로그래밍 ] fork()와 execve()의 차이를 알아보자
sangjun
·2022. 4. 14. 18:56
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);
}