舉例講解C語(yǔ)言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法
先來(lái)看這樣一個(gè)例子,利用fork調(diào)用execlp()函數(shù)來(lái)在Linux下實(shí)現(xiàn)ps或ls命令:
#include "sys/types.h" #include "unistd.h" #include "stdio.h" #include "stdlib.h" int main() { pid_t result; result=fork(); //報(bào)錯(cuò)處理 if(result==-1) { printf("Fork Error\n"); } //son else if(result==0) {//調(diào)用execlp()函數(shù),相當(dāng)于"ps -ef" if((result=execlp("ps","ps",NULL))<0); printf("son\n"); } //father else { if((result=execlp("ls","ls",NULL))<0); printf("father\n"); } }
一般來(lái)講, 我們編寫1個(gè)普通的c程序, 運(yùn)行這個(gè)程序直到程序結(jié)束, 系統(tǒng)只會(huì)分配1個(gè)pid給這個(gè)程序, 也就就說(shuō), 系統(tǒng)里只會(huì)有一條關(guān)于這個(gè)程序的進(jìn)程.
但是執(zhí)行了fork() 這個(gè)函數(shù)就不同了.
fork 這個(gè)英文單詞在英文里是"分叉"意思, fork() 這個(gè)函數(shù)作用也很符合這個(gè)意思. 它的作用是復(fù)制當(dāng)前進(jìn)程(包括進(jìn)程在內(nèi)存里的堆棧數(shù)據(jù))為1個(gè)新的鏡像. 然后這個(gè)新的鏡像和舊的進(jìn)程同時(shí)執(zhí)行下去. 相當(dāng)于本來(lái)1個(gè)進(jìn)程, 遇到fork() 函數(shù)后就分叉成兩個(gè)進(jìn)程同時(shí)執(zhí)行了. 而且這兩個(gè)進(jìn)程是互不影響
參考下面這個(gè)小程序:
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; }
在這個(gè)函數(shù)里, 共有兩條printf語(yǔ)句, 但是執(zhí)行執(zhí)行時(shí)則打出了3行信息. 如下圖:
為什么呢, 因?yàn)閒ork()函數(shù)將這個(gè)程序分叉了啊, 見(jiàn)下面的圖解:
可以見(jiàn)到程序在fork()函數(shù)執(zhí)行時(shí)都只有1條主進(jìn)程, 所以 step 1 會(huì)被打印輸出1次.
執(zhí)行 fork()函數(shù)后, 程序分叉成為了兩個(gè)進(jìn)程, 1個(gè)是原來(lái)的主進(jìn)程, 另1個(gè)是新的子進(jìn)程, 它們都會(huì)執(zhí)行fork() 函數(shù)后面的代碼, 所以 step2 會(huì)被 兩條進(jìn)程分別打印輸出各一次, 屏幕上就總共3條printf 語(yǔ)句了!
可以見(jiàn)到這個(gè)函數(shù)最后面我用了 scanf()函數(shù)來(lái)防止程序退出, 這時(shí)查看系統(tǒng)的進(jìn)程, 就會(huì)發(fā)現(xiàn)兩個(gè)相同名字的進(jìn)程:
如上圖, pid 8808 那個(gè)就是主進(jìn)程了, 而 pid 8809那個(gè)就是子進(jìn)程啊, 因?yàn)樗膒arent pid是 8808啊!
需要注意的是, 假如沒(méi)有做特殊處理, 子進(jìn)程會(huì)一直存在, 即使fork_3()函數(shù)被調(diào)用完成, 子進(jìn)程會(huì)和主程序一樣,返回調(diào)用fork_3() 函數(shù)的上一級(jí)函數(shù)繼續(xù)執(zhí)行, 直到整個(gè)程序退出.
可以看出, 假如fork_3() 被執(zhí)行2次, 主程序就會(huì)分叉兩次, 最終變成4個(gè)進(jìn)程, 是不是有點(diǎn)危險(xiǎn). 所以上面所謂的特殊處理很重要啊!
區(qū)別分主程序和子程序
實(shí)際應(yīng)用中, 單純讓程序分叉意義不大, 我們新增一個(gè)子程序, 很可能是為了讓子進(jìn)程單獨(dú)執(zhí)行一段代碼. 實(shí)現(xiàn)與主進(jìn)程不同的功能.
要實(shí)現(xiàn)上面所說(shuō)的功能, 實(shí)際上就是讓子進(jìn)程和主進(jìn)程執(zhí)行不同的代碼啊.
所以fork() 實(shí)際上有返回值, 而且在兩條進(jìn)程中的返回值是不同的, 在主進(jìn)程里 fork()函數(shù)會(huì)返回主進(jìn)程的pid, 而在子進(jìn)程里會(huì)返回0! 所以我們可以根據(jù)fork() 的返回值來(lái)判斷進(jìn)程到底是哪個(gè)進(jìn)程, 就可以利用if 語(yǔ)句來(lái)執(zhí)行不同的代碼了!
如下面這個(gè)小程序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"); }
我對(duì)fork() 函數(shù)的返回值進(jìn)行了判斷, 如果 返回值是0, 我就讓認(rèn)為它是子進(jìn)程, 否則是主程序. 那么我就可以讓這兩條進(jìn)程輸出不同的信息了.
輸出信息如下圖:
可以見(jiàn)到 子程序和主程序分別輸出了8條不同的信息, 但是它們并不是規(guī)則交替輸出的, 因?yàn)樗鼈儍蓷l進(jìn)程是互相平行影響的, 誰(shuí)的手快就在屏幕上先輸出, 每次運(yùn)行的結(jié)果都有可能不同哦.
下面是圖解:
由圖解知兩條進(jìn)程都對(duì)fork()返回值執(zhí)行判斷, 在if 判斷語(yǔ)句中分別執(zhí)行各自的代碼. 但是if判斷完成后, 還是會(huì)回各自執(zhí)行接下來(lái)的代碼. 所以 step2 還是輸出了2次.
上一篇:DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--定點(diǎn)數(shù)的加減乘除運(yùn)算
欄 目:C語(yǔ)言
下一篇:DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)與定點(diǎn)概述
本文標(biāo)題:舉例講解C語(yǔ)言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2222.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文