a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

舉例講解C語言的fork()函數創建子進程的用法

2020-01-26 14:32:32
字體:
來源:轉載
供稿:網友

先來看這樣一個例子,利用fork調用execlp()函數來在Linux下實現ps或ls命令:

#include "sys/types.h"#include "unistd.h"#include "stdio.h"#include "stdlib.h"int main(){ pid_t result; result=fork(); //報錯處理 if(result==-1) {  printf("Fork Error/n"); } //son else if(result==0) {//調用execlp()函數,相當于"ps -ef" if((result=execlp("ps","ps",NULL))<0);          printf("son/n"); } //father    else  { if((result=execlp("ls","ls",NULL))<0);         printf("father/n"); }} 

一般來講, 我們編寫1個普通的c程序, 運行這個程序直到程序結束, 系統只會分配1個pid給這個程序, 也就就說, 系統里只會有一條關于這個程序的進程.
但是執行了fork() 這個函數就不同了.
fork 這個英文單詞在英文里是"分叉"意思,  fork() 這個函數作用也很符合這個意思.  它的作用是復制當前進程(包括進程在內存里的堆棧數據)為1個新的鏡像. 然后這個新的鏡像和舊的進程同時執行下去. 相當于本來1個進程, 遇到fork() 函數后就分叉成兩個進程同時執行了. 而且這兩個進程是互不影響
參考下面這個小程序:

int fork_3(){   printf("it's the main process step 1!!/n/n");    fork();    printf("step2 after fork() !!/n/n");    int i; scanf("%d",&i);  //prevent exiting   return 0; } 

在這個函數里, 共有兩條printf語句, 但是執行執行時則打出了3行信息. 如下圖:

2016622162533778.png (246×100)

為什么呢, 因為fork()函數將這個程序分叉了啊,  見下面的圖解:

2016622162600978.png (796×291)

可以見到程序在fork()函數執行時都只有1條主進程, 所以 step 1 會被打印輸出1次.
執行 fork()函數后,  程序分叉成為了兩個進程, 1個是原來的主進程,  另1個是新的子進程, 它們都會執行fork() 函數后面的代碼, 所以 step2 會被 兩條進程分別打印輸出各一次, 屏幕上就總共3條printf 語句了!
可以見到這個函數最后面我用了 scanf()函數來防止程序退出,  這時查看系統的進程, 就會發現兩個相同名字的進程:

2016622162622859.png (574×62)

如上圖, pid 8808 那個就是主進程了, 而 pid  8809那個就是子進程啊, 因為它的parent pid是 8808啊!
需要注意的是, 假如沒有做特殊處理, 子進程會一直存在, 即使fork_3()函數被調用完成,  子進程會和主程序一樣,返回調用fork_3() 函數的上一級函數繼續執行, 直到整個程序退出.
可以看出, 假如fork_3() 被執行2次,  主程序就會分叉兩次, 最終變成4個進程, 是不是有點危險. 所以上面所謂的特殊處理很重要啊!

區別分主程序和子程序
實際應用中, 單純讓程序分叉意義不大, 我們新增一個子程序, 很可能是為了讓子進程單獨執行一段代碼. 實現與主進程不同的功能.
要實現上面所說的功能, 實際上就是讓子進程和主進程執行不同的代碼啊.
所以fork() 實際上有返回值, 而且在兩條進程中的返回值是不同的, 在主進程里 fork()函數會返回主進程的pid,   而在子進程里會返回0!   所以我們可以根據fork() 的返回值來判斷進程到底是哪個進程, 就可以利用if 語句來執行不同的代碼了!
如下面這個小程序fork_1():

int fork_1(){   int childpid;   int i;    if (fork() == 0){     //child process     for (i=1; i<=8; i++){       printf("This is child process/n");     }   }else{     //parent process     for(i=1; i<=8; i++){       printf("This is parent process/n");     }   }    printf("step2 after fork() !!/n/n"); } 

我對fork() 函數的返回值進行了判斷, 如果 返回值是0, 我就讓認為它是子進程, 否則是主程序.  那么我就可以讓這兩條進程輸出不同的信息了.
輸出信息如下圖:

2016622162641880.jpg (720×337)

可以見到 子程序和主程序分別輸出了8條不同的信息,  但是它們并不是規則交替輸出的, 因為它們兩條進程是互相平行影響的, 誰的手快就在屏幕上先輸出,  每次運行的結果都有可能不同哦.
下面是圖解:

2016622162704009.png (1024×384)

由圖解知兩條進程都對fork()返回值執行判斷,  在if 判斷語句中分別執行各自的代碼.  但是if判斷完成后,  還是會回各自執行接下來的代碼. 所以 step2 還是輸出了2次.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 国产成人福利 | 色婷婷香蕉在线一区二区 | 可以免费观看的av | 成人免费在线视频观看 | 久久99精品久久久噜噜最新章节 | 日本中文字幕在线视频 | 久久久久久久久久久成人 | v片网站| 日韩精品无玛区免费专区又长又大 | 日韩高清在线 | 午夜影院在线观看视频 | 91亚洲国产成人久久精品网站 | 欧美一级二级三级 | 久久精品视频网 | 不卡av电影在线观看 | av一区二区在线观看 | 日韩国产综合 | 国产精品久久久久国产a级 一区二区三区在线 | 91久久国产综合久久 | 日日射av | 9色网站 | 国产精品理论视频 | 青草青草久热精品视频在线观看 | 中文字幕av高清 | 欧美一级片在线观看 | 欧美成人区 | 成人在线日韩 | 亚洲国产精品99久久久久久久久 | 久久久久久久久一区 | 欧美激情一区二区三区蜜桃视频 | 操操日 | 理论片一区| 亚洲国产精久久久久久久 | 国产成人在线播放 | 国产一级在线 | 冲田杏梨毛片 | 人人草人人 | 成人精品视频 | 最新中文字幕在线观看 | 欧美一级毛片日韩一级 | 精品国产区 |