進程應用之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

在這裏插入圖片描述

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