#include <unistd.h>
pid_t fork(void);
作用:創建一個子進程。
到目前為止,我們可以直到兩種創建進程的方法:1. 通過執行二進制文件來創建一個進程,如:./a.out? /bin/ls;2.通過fork函數來創建一個子進程。
該函數沒有形參,返回值類型為pid_t,為無符號整型。而進程的id為正整數。如果失敗,則返回-1;如果成功,則由于父進程(調用fork函數的進程)創建了一個子進程,因此父進程與子進程都會有一個fork函數,一個fork函數變為了兩個fork函數,從而就會有兩個返回值,父進程的fork返回子進程的id,其值大于0,子進程的fork返回0,表示進程創建成功,因此可以根據返回值來判斷哪個是父進程,哪個是子進程。
注意:注意返回值,不是fork函數能返回兩個值,而是fork后,fork函數變為兩個,父子需各自返回一個。
?
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
作用:getpid返回當前進程(調用這一函數的進程)的ID;getppid返回當前進程的父進程的ID。都無形參。 這兩個函數總是成功,因此返回值大于0。
//代碼示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{pid_t pid; //id為pid_t類型printf("xxxxxxxxxxx\n"); //這部分只是父進程執行,子進程雖然有這部分的代碼,但是不執行,而是從創建處開始向下執行。pid = fork(); //此處產生了一個子進程if(pid == -1){perror("fork");exit(1);}else if(pid == 0) //如果是子進程printf("This is child process, and the pid = %u, the ppid = %u\n",getpid( ),getppid( ));else //如果是父進程{printf("This is parent process, and the pid = %u, the ppid = %u\n",getpid( ),getppid( ));sleep(1); // 保證子進程比父進程先結束}printf("yyyyyyyyyyyy, the pid = %u\n",getpid( )); //父子進程都要執行這段代碼return 0;
}
[root@localhost fork]# ./fork_test1
xxxxxxxxxxx? ?//只是父進程執行
This is parent process, and the pid = 14652, the ppid = 4199? //父進程也有父進程
yyyyyyyyyyyy, the pid = 14652 ?//父進程執行
This is child process, and the pid = 14653, the ppid = 14652? //子進程
yyyyyyyyyyyy, the pid = 14653 ?//子進程執行
由上可以看出,fork后的代碼,父子進程都執行,fork前的代碼只是父進程執行,雖然子進程也包含這段代碼,但其只是從創建處開始執行。
[root@localhost fork]# ps aux | grep 4199? ?//查看父進程的父進程
root?????? 4199? 0.0? 0.1 116352? 3160 pts/0??? Ss?? Mar24?? 0:01 -bash
root????? 14722? 0.0? 0.0 112644?? 972 pts/0??? S+?? 00:18?? 0:00 grep --color=auto 4199
可以看到,父進程的父進程中斷為bash解釋器,即終端進程,其在執行二進制文件時,也通過fork函數創建一個子進程來完成該二進制文件(./fork_test1)的執行,其原理與父進程創建子進程原理一樣。