日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

循环创建N个子进程

發布時間:2023/11/30 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 循环创建N个子进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以循環創建5個進程為例,給出如下代碼,分析其錯誤

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(void) {int i;pid_t pid;printf("xxxxxxxxxxx\n");for (i = 0; i < 5; i++){pid = fork( ); if(pid == -1){printf("process of %u creat process failurely!\n",getpid( ));perror("fork");}else if(pid == 0){printf("I'am %dth child , pid = %u\n", i+1, getpid());}else{printf("I'am parent, pid = %u\n",getpid());}}printf("yyyyyyyyyy\n");return 0; }

分析:首先在shell中執行該文件時,由終端進程fork產生一個子進程來執行該程序,然后在for循環體中,子進程在創建一個個的孫進程。在上述for循環體中,i=0時,父進程創建了一個子進程,此時父進程與子進程的i都為0(剛fork后兩個的i相等,但是以后不一定相等,它們各自獨立)。此時有兩個進程(父、子進程)都會開始向下執行,即后面的代碼都一樣的執行,各個進程一直執行到return語句后,各個進程才會自動終止(結束)。上述,在for循環體中創建的子進程,又會在下一次循環中繼續去創建子進程,因此最終并不僅僅創建的是5個進程,而是共創建了25-1個進程,總共25個進程。如果循環n次,則總共為2n個進程。

因此,需要在循環的過程,保證子進程不再執行fork ,因此當(fork() == 0)時,子進程應該立即break;才正確(即跳出循環體)。

?

練習:通過命令行參數指定創建進程的個數,如:第1個子進程休眠0秒打印:“我是第1個子進程”;第2個進程休眠1秒打印:“我是第2個子進程”;第3個進程休眠2秒打印:“我是第3個子進程。”

通過該練習掌握框架:循環創建n個子進程,使用循環因子i對創建的子進程加以區分。

//代碼如下:

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char *argv[ ]) {if(argc < 2){printf("./a.out 5\n");exit(1);}int i;pid_t pid;printf("xxxxxxxxxxx\n");long int a = strtol(argv[1],NULL,10); //將字符串轉化為10進制整數for (i = 0; i < a; i++){pid = fork( ); //創建子進程if(pid == -1){printf("process of %u creat process failurely!\n",getpid( )); perror("fork");} //判斷創建進程是否成功,如果當次循環創建不成功,則不結束該進程,進行下一次循環,再次嘗試創建(這樣等效于少了一次循環)。else if(pid == 0) //如果為子進程,則跳出循環{break;}else //否則(父進程),不執行操作,進入下一次循環;}sleep(i); //通過i值來區分進程,可見父進程睡眠時間最久,為a秒,最先創建的子進程睡眠時間最少,為0秒。if(i < 5)printf("I'am the %dth child process, the ID = %u\n",i+1,getpid( )); //子進程輸出elseprintf("I'am parent process, the ID = %u\n",getpid( )); //父進程輸出return 0; }

[root@localhost fork]# ./fork_test 5? //shell終端fork產生子進程來運行這一程序

xxxxxxxxxxx?

I'am the 1th child process, the ID = 16507

I'am the 2th child process, the ID = 16508

I'am the 3th child process, the ID = 16509

I'am the 4th child process, the ID = 16510

I'am the 5th child process, the ID = 16511

I'am parent process, the ID = 16506

[root@localhost fork]#

分析:之所以要引入sleep函數,來使各個進程睡眠,是為了確保父進程最后結束(即最后執行return),且越先創建的子進程越先能夠結束。而在創建進程后,每個進程的i值都由自己維護,都要從創建處開始執行自己的代碼,從而i值發生改變。因此就可以用i來區分是哪一個進程,從而越先創建的進程睡眠時間越少,第i個子進程睡眠時間為i-1秒。下面深度分析sleep函數,代碼如下:

//與上面的代碼相比,只是去掉了一行內容: sleep(i);? 因此不再列出,其執行結果如下:

[root@localhost fork]# ./fork_test 5

xxxxxxxxxxx

I'am parent process, the ID = 16702

I'am the 3th child process, the ID = 16705

[root@localhost fork]# I'am the 1th child process, the ID = 16703

I'am the 2th child process, the ID = 16704

I'am the 5th child process, the ID = 16707

I'am the 4th child process, the ID = 16706

pwd?? //正常執行shell中的pwd命令(前面標簽已經輸出)

/mnt/hgfs/share/01_process_test/fork

[root@localhost fork]#

?

分析:由上可以看出,在沒有sleep( )函數的控制下,每個進程的結束先后順序是隨機的,沒法控制的。在上述程序執行過程中,總共參與了7個進程:shell終端進程、父進程(由shell終端fork產生)和5個子進程(由父進程fork產生),這7個進程對CPU的搶占是公平的(隨機的),無法預測。注意一點:父進程只能夠知道其子進程是否結束,而不能直到其孫進程是什么狀態,這7個進程共同使用這一個終端,當shell中執行. /fork_test 5時,shell進程會把前臺交給其子進程使用,一旦子進程結束(執行了return后),shell進程知道并馬上收回前臺,并輸出[root@localhost fork]# 光標? 等待與用戶再次交互(此時shell進程放棄了CPU,將自己阻塞起來,等待用戶的命令),但是此時那5個子進程并不一定就結束了,因此未結束的進程將會繼續占用CPU,直到執行到return并結束。因此,這些進程的輸出結果會在 [root@localhost fork]#的后面。CPU1s內可執行上億條指令,因此睡1s可以絕對保證進程可以按照希望的順序執行。

總結

以上是生活随笔為你收集整理的循环创建N个子进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。