如果要了解進程和線程的區別請參考:進程和線程的描述
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