這段時間打算把以前學的東西好好做個總結,免得總是學一樣,忘一樣。Linux下的C編程,就從利用fork開闢一個新的進程開始吧。
最開始接觸fork的時候,覺得這個函數確實很有意思,一次調用,兩次返回,看看下面這段程式:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<sys/types.h>
5
6 int main(int argc, char *argv[])
7 {
8 pid_t pid; /*儲存進程號 */
9
10 pid = fork(); /*產生新的進程 */
11
12 if (pid < 0) { /*如果建立進程失敗 */
13 printf("Error!\n");
14 exit(-1);
15 } else if (pid == 0) { /*如果進入子進程 */
16 printf("This is a child process,");
17 printf("My pid is %d\n", getpid());
18 } else {
19 printf("This is parent process,"); /*如果是父進程 */
20 printf("My pid is %d\n", getpid());
21 }
22
23 return 0;
24
運行結果如下:
This is parent process,My pid is 2945
This is a child process,My pid is 2946
最初對這個確實感到很疑惑,C語言不是規定一個函數只能有一個傳回值嗎?這個怎麼可以返回兩次,而且讓程式也重複執行了兩次。後來才知道,原來是fork“搞的鬼”,程式在fork處就已經開始“分裂”成兩個進程了,當程式運行在子進程的時候,其fork傳回值為0,這就是else if (pid == 0)這個選擇分枝;而當程式運行在父進程中的時候,其傳回值就是子進程的pid;最壞的情況,就是開闢進程失敗,這個時候,系統通常會返回一個負數if(pid < 0),可以利用error來判斷是什麼錯誤,不過,我這個程式中為了簡單起見,並沒有對該錯誤進行判斷。
在進程結束後,調用exit()來退出進程,但是大家會發現,在上面的程式中,除了在建立線程失敗後調用了exit(),其他的地方,並沒有使用exit(),只在程式最後有個return,以前一直以為其實return就代替了exit(),不過今天在看《Linux 核心設計與實現》的時候,發現上面提到了這一點,其實在編譯的時候,編譯器在mian()函數的retrurn後面加了個exit(),原來,exit()還是有的,只不過我平時沒有注意到而已。