1. 程式人生 > >fork、getpid函式的程序小知識

fork、getpid函式的程序小知識

getpid函式與fork函式都是與程序有關的函式。

getpid函式原型為: pid_t getpid(void);

函式返回值為當前程序的PID。吐槽一下《UNIX環境高階程式設計》的中文版翻譯,將它翻譯為“呼叫程序的程序ID”,很容易讓人誤解成是當前程序的父程序ID。仔細閱讀getpid的man手冊,介紹getpid功能時,就一句:“get process identification”,而下面的詳解中提到返回值是“returns the process ID of the calling process”。簡單地將“the calling process”翻譯成“呼叫程序”,似乎不太好。

fork函式原型為: pid_t fork(void);

函式返回值有三種情況:

                在子程序中返回0

              在父程序中返回子程序ID,一般大於0。

                出錯時返回-1

意思很明確,儘管如此,卻還是有幾個地方容易讓人誤解。

第一:子程序與父程序共享哪些資料?哪些程式?

這裡有一個很簡單的例子,比如在fork之前的printf語句,會不會被子程序列印?答案是不會,因為該語句已被執行。而在fork之前的資料,卻會複製到子程序中。

第二:子程序難道與父程序完全一樣嗎?

 在沒有執行exec之前,確實是一樣的,只不過fork在父子程序中的返回值是不一樣的。可以通過這個特性使用if語句改變程式執行順序。

第三:子程序的父程序消失以後,子程序歸誰管?

由一個程序號為1的傢伙代管,據說這傢伙叫init程序,非常博愛,是所有孤兒程序的父程序,所謂孤兒程序,就是找不到產生自己的父程序的子程序。有些亂,但真相就是這樣的。

以一個程式碼示例來說明:

複製程式碼
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main(){
        pid_t tmp5;
       pid_t tmp;

        tmp5=getpid();
        printf("parent pid %d\n
",tmp5); /* 返回當前程序的程序ID */ pid_t tmp4=getppid(); printf("%d's parent pid is %d\n",tmp,tmp4); /* 返回呼叫當前程序的程序ID */ tmp=fork(); if(tmp < 0){ printf("error happans in fork\n"); exit(1); } else if(0== tmp){ /* 子程序 fork 返回值為0 */ printf("\n\n"); printf("tmp == %d\n, is child process\n",tmp); pid_t tmp1=getpid(); printf("child id is: %d\n",tmp1); pid_t tmp2=getppid(); printf("%d's parent id is: %d\n",tmp1,tmp2); /* getppid的返回值tmp2可能為1,或者tmp3,取決於程序排程 */ }else{ /* 父程序fork 返回值為子程序id */ printf("\n\n"); printf("tmp == %d\n, tmp is child pid\n",tmp); pid_t tmp3=getpid(); printf("parent pid is %d\n",tmp3); /* 獲取當前程序id,應該與程式最早列印的程序id 值相同 */ sleep(10); /* 假設沒有sleep(10)這一句,父程序立即執行完畢後消失,而子程序可能後於它消失,成為孤兒程序 */ } return 0; }
複製程式碼


一個執行結果:

parent pid 18302
32767's parent pid is 17881



tmp == 18303
, tmp is child pid

parent pid  is 18302
tmp == 0
, is child process
child id is: 18303
18303's parent id is: 18302