进程应用之fork 和 execve

如果要了解进程和线程的区别请参考:进程和线程的描述

1.fork()函数介绍

#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);

这个函数虽然执行一次,但是会返回2次的不同的值。就是在这里一个进程会变为两个进程,原本的进程叫做父进程,新的进程叫子进程。父进程中返回的值为子进程的ID号。而子进程中返回的是0.

调用这个函数后就产生了2个进程,但是此时的两个进程还没有真正的拥有两个独立的资源,还是共用的一份。只用当其中一个进程发生写的动作,系统才会分配一份新的资源给这个进程。此时才是各自拥有独立的资源。这个叫做写时复用。比如通过函数execve()执行新的程序。

2.execve()函数介绍

#include<unistd.h>
int execve(const char *file, const char *argv[] const char *envp[]);

参数1:要执行的文件
参数2:执行文件后面跟着的参数,可以是NULL;
参数3:环境变量

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

int main()
{
        pid_t pid;
        pid = fork();
        if(pid > 0)  {
                while(1) {
                printf("c : %d, re : %d  f : %d\n", pid, getpid(), getppid());
                sleep(1);
                }
        } else if(pid == 0) {
                        char *args[] = {"/bin/ls", NULL};
                        execve("/bin/ls", args, NULL);
                        printf("Process test\n");
                        printf("c : %d, re : %d  f : %d\n", pid, getpid(), getppid());
        } else {
                printf("process failed\n");
        }
        return 0;
}

这个函数的意思是,通过fork产生两个进程,父进程执行while(1)打印信息,子进程执行ls命令。你会发现子进程中的打印函数并没有执行,这就是通过execve()执行ls后,子进程就被分配了独立的资源,就进入独立的资源里面去执行,后面的两个打印函数就不是子进程的资源了。如果吧execve去掉就会发现打印会执行,这时就是父子进程共用资源。 只有在execve()执行,就是子进程要发生写时,资源才会分配给它,即为写时复用。

kayshi@ubuntu:~/code/Process$ ./a.out 
c : 10086, re : 10085  f : 2157
a.out  fork.c
c : 10086, re : 10085  f : 2157
c : 10086, re : 10085  f : 2157
c : 10086, re : 10085  f : 2157
c : 10086, re : 10085  f : 2157
c : 10086, re : 10085  f : 2157
c : 10086, re : 10085  f : 2157

通过pstree可以查看进程树
在这里插入图片描述
bash进程下,产生了我们要执行的进程a.out 然后有产生了新的子进程ls

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章