當(dāng)前位置:首頁 > 嵌入式 > 嵌入式教程
[導(dǎo)讀]通過編寫多進(jìn)程程序,使讀者熟練掌握fork()、exec()、wait()和waitpid()等函數(shù)的使用,進(jìn)一步理解在Linux中多進(jìn)程編程的步驟。

7.4實(shí)驗(yàn)內(nèi)容7.4.1編寫多進(jìn)程程序1.實(shí)驗(yàn)?zāi)康?p>通過編寫多進(jìn)程程序,使讀者熟練掌握fork()、exec()、wait()和waitpid()等函數(shù)的使用,進(jìn)一步理解在Linux中多進(jìn)程編程的步驟。

2.實(shí)驗(yàn)內(nèi)容

該實(shí)驗(yàn)有3個(gè)進(jìn)程,其中一個(gè)為父進(jìn)程,其余兩個(gè)是該父進(jìn)程創(chuàng)建的子進(jìn)程,其中一個(gè)子進(jìn)程運(yùn)行“ls-l”指令,另一個(gè)子進(jìn)程在暫停5s之后異常退出,父進(jìn)程先用阻塞方式等待第一個(gè)子進(jìn)程的結(jié)束,然后用非阻塞方式等待另一個(gè)子進(jìn)程的退出,待收集到第二個(gè)子進(jìn)程結(jié)束的信息,父進(jìn)程就返回。

3.實(shí)驗(yàn)步驟

(1)畫出該實(shí)驗(yàn)流程圖。

該實(shí)驗(yàn)流程圖如圖7.8所示。

圖7.8實(shí)驗(yàn)7.4.1流程圖

(2)實(shí)驗(yàn)源代碼。

先看一下下面的代碼,這個(gè)程序能得到我們所希望的結(jié)果嗎,它的運(yùn)行會產(chǎn)生幾個(gè)進(jìn)程?請讀者回憶一下fork()調(diào)用的具體過程。

/*multi_proc_wrong.c*/

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<unistd.h>

#include<sys/wait.h>

intmain(void)

{

pid_tchild1,child2,child;

/*創(chuàng)建兩個(gè)子進(jìn)程*/

child1=fork();

child2=fork();

/*子進(jìn)程1的出錯(cuò)處理*/

if(child1==-1)

{

printf("Child1forkerrorn");

exit(1);

}

elseif(child1==0)/*在子進(jìn)程1中調(diào)用execlp()函數(shù)*/

{

printf("Inchild1:execute'ls-l'n");

if(execlp("ls","ls","-l",NULL)<0)

{

printf("Child1execlperrorn");

}

}

if(child2==-1)/*子進(jìn)程2的出錯(cuò)處理*/

{

printf("Child2forkerrorn");

exit(1);

}

elseif(child2==0)/*在子進(jìn)程2中使其暫停5s*/

{

printf("Inchild2:sleepfor5secondsandthenexitn");

sleep(5);

exit(0);

}

else/*在父進(jìn)程中等待兩個(gè)子進(jìn)程的退出*/

{

printf("Infatherprocess:n");

child=waitpid(child1,NULL,0);/*阻塞式等待*/

if(child==child1)

{

printf("Getchild1exitcoden");

}

else

{

printf("Erroroccured!n");

}

do

{

child=waitpid(child2,NULL,WNOHANG);/*非阻塞式等待*/

if(child==0)

{

printf("Thechild2processhasnotexited!n");

sleep(1);

}

}while(child==0);

if(child==child2)

{

printf("Getchild2exitcoden");

}

else

{

printf("Erroroccured!n");

}

}

exit(0);

}

編譯和運(yùn)行以上代碼,并觀察其運(yùn)行結(jié)果。它的結(jié)果是我們所希望的嗎?

看完前面的代碼之后,再觀察下面的代碼,它們之間有什么區(qū)別,會解決哪些問題。

/*multi_proc.c*/

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<unistd.h>

#include<sys/wait.h>

intmain(void)

{

pid_tchild1,child2,child;

/*創(chuàng)建兩個(gè)子進(jìn)程*/

child1=fork();

/*子進(jìn)程1的出錯(cuò)處理*/

if(child1==-1)

{

printf("Child1forkerrorn");

exit(1);

}

elseif(child1==0)/*在子進(jìn)程1中調(diào)用execlp()函數(shù)*/

{

printf("Inchild1:execute'ls-l'n");

if(execlp("ls","ls","-l",NULL)<0)

{

printf("Child1execlperrorn");

}

}

else/*在父進(jìn)程中再創(chuàng)建進(jìn)程2,然后等待兩個(gè)子進(jìn)程的退出*/

{

child2=fork();

if(child2==-1)/*子進(jìn)程2的出錯(cuò)處理*/

{

printf("Child2forkerrorn");

exit(1);

}

elseif(child2==0)/*在子進(jìn)程2中使其暫停5s*/

{

printf("Inchild2:sleepfor5secondsandthenexitn");

sleep(5);

exit(0);

}

printf("Infatherprocess:n");

child=waitpid(child1,NULL,0);/*阻塞式等待*/

if(child==child1)

{

printf("Getchild1exitcoden");

}

else

{

printf("Erroroccured!n");

}

do

{

child=waitpid(child2,NULL,WNOHANG);/*非阻塞式等待*/

if(child==0)

{

printf("Thechild2processhasnotexited!n");

sleep(1);

}

}while(child==0);

if(child==child2)

{

printf("Getchild2exitcoden");

}

else

{

printf("Erroroccured!n");

}

}

exit(0);

}

(3)首先在宿主機(jī)上編譯調(diào)試該程序:

$gccmulti_proc.c–omulti_proc(或者使用Makefile)

(4)在確保沒有編譯錯(cuò)誤后,使用交叉編譯該程序:

$arm-linux-gccmulti_proc.c–omulti_proc(或者使用Makefile)

(5)將生成的可執(zhí)行程序下載到目標(biāo)板上運(yùn)行。

4.實(shí)驗(yàn)結(jié)果

在目標(biāo)板上運(yùn)行的結(jié)果如下所示(具體內(nèi)容與各自的系統(tǒng)有關(guān)):

$./multi_proc

Inchild1:execute'ls-l'/*子進(jìn)程1的顯示,以下是“ls–l”的運(yùn)行結(jié)果*/

total28

-rwxr-xr-x1davidroot2322008-07-1804:18Makefile

-rwxr-xr-x1davidroot87682008-07-2019:51multi_proc

-rw-r--r--1davidroot14792008-07-2019:51multi_proc.c

-rw-r--r--1davidroot34282008-07-2019:51multi_proc.o

-rw-r--r--1davidroot14632008-07-2018:55multi_proc_wrong.c

Inchild2:sleepfor5secondsandthenexit/*子進(jìn)程2的顯示*/

Infatherprocess:/*以下是父進(jìn)程顯示*/

Getchild1exitcode/*表示子進(jìn)程1結(jié)束(阻塞等待)*/

Thechild2processhasnotexited!/*等待子進(jìn)程2結(jié)束(非阻塞等待)*/

Thechild2processhasnotexited!

Thechild2processhasnotexited!

Thechild2processhasnotexited!

Thechild2processhasnotexited!

Getchild2exitcode/*表示子進(jìn)程2終于結(jié)束了*/

因?yàn)閹讉€(gè)子進(jìn)程的執(zhí)行有競爭關(guān)系,因此,結(jié)果中的順序是隨機(jī)的。讀者可以思考,怎樣才可以保證子進(jìn)程的執(zhí)行順序呢?

7.4.2編寫守護(hù)進(jìn)程1.實(shí)驗(yàn)?zāi)康?p>通過編寫一個(gè)完整的守護(hù)進(jìn)程,使讀者掌握守護(hù)進(jìn)程編寫和調(diào)試的方法,并且進(jìn)一步熟悉如何編寫多進(jìn)程程序。

2.實(shí)驗(yàn)內(nèi)容

在該實(shí)驗(yàn)中,讀者首先建立起一個(gè)守護(hù)進(jìn)程,然后在該守護(hù)進(jìn)程中新建一個(gè)子進(jìn)程,該子進(jìn)程暫停10s,然后自動(dòng)退出,并由守護(hù)進(jìn)程收集子進(jìn)程退出的消息。在這里,子進(jìn)程和守護(hù)進(jìn)程的退出消息都在系統(tǒng)日志文件(例如“/var/log/messages”,日志文件的全路徑名因版本的不同可能會有所不同)中輸出。子進(jìn)程退出后,守護(hù)進(jìn)程循環(huán)暫停,其間隔時(shí)間為10s。

3.實(shí)驗(yàn)步驟

(1)畫出該實(shí)驗(yàn)流程圖。

該程序流程圖如圖7.9所示。

圖7.9實(shí)驗(yàn)7.4.2流程圖

(2)實(shí)驗(yàn)源代碼。

具體代碼設(shè)置如下:

/*daemon_proc.c*/

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<unistd.h>

#include<sys/wait.h>

#include<syslog.h>

intmain(void)

{

pid_tchild1,child2;

inti;

/*創(chuàng)建子進(jìn)程1*/

child1=fork();

if(child1==1)

{

perror("child1fork");

exit(1);

}

elseif(child1>0)

{

exit(0);/*父進(jìn)程退出*/

}

/*打開日志服務(wù)*/

openlog("daemon_proc_info",LOG_PID,LOG_DAEMON);

/*以下幾步是編寫守護(hù)進(jìn)程的常規(guī)步驟*/

setsid();

chdir("/");

umask(0);

for(i=0;i<getdtablesize();i++)

{

close(i);

}

/*創(chuàng)建子進(jìn)程2*/

child2=fork();

if(child2==1)

{

perror("child2fork");

exit(1);

}

elseif(child2==0)

{/*進(jìn)程child2*/

/*在日志中寫入字符串*/

syslog(LOG_INFO,"child2willsleepfor10s");

sleep(10);

syslog(LOG_INFO,"child2isgoingtoexit!");

exit(0);

}

else

{/*進(jìn)程child1*/

waitpid(child2,NULL,0);

syslog(LOG_INFO,"child1noticedthatchild2hasexited");

/*關(guān)閉日志服務(wù)*/

closelog();

while(1)

{

sleep(10);

}

}

}

(3)由于有些嵌入式開發(fā)板沒有syslog服務(wù),讀者可以在宿主機(jī)上編譯運(yùn)行。

$gccdaemon_proc.c–odaemon_proc(或者使用Makefile)

(4)運(yùn)行該程序。

(5)等待10s后,以root身份查看系統(tǒng)日志文件(例如“/var/log/messages”)。

(6)使用ps–ef|grepdaemon_proc查看該守護(hù)進(jìn)程是否在運(yùn)行。

4.實(shí)驗(yàn)結(jié)果

(1)在系統(tǒng)日志文件中有類似如下的信息顯示:

Jul2021:15:08localhostdaemon_proc_info[4940]:child2willsleepfor10s

Jul2021:15:18localhostdaemon_proc_info[4940]:child2isgoingtoexit!

Jul2021:15:18localhostdaemon_proc_info[4939]:child1noticedthatchild2hasexited

讀者可以從時(shí)間戳里清楚地看到child2確實(shí)暫停了10s。

(2)使用命令ps–ef|grepdaemon_proc可看到如下結(jié)果:

david49391021:15?00:00:00./daemon_proc

可見,daemon_proc確實(shí)一直在運(yùn)行。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉