#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { printf("本程式的程式編號是:%d\n",getpid()); int ipid=fork(); sleep(1); // sleep等待程式的生成。 printf("pid=%d\n",ipid); if (ipid!=0) printf("父程式編號是:%d\n",getpid()); else printf("子程式編號是:%d\n",getpid()); sleep(30); // 是為了方便檢視程式在shell下用ps -ef|grep book252檢視本程式的編號。 }
執行結果
初學者可能用點接受不了現實。
1)一個函式(fork)返回了兩個值?
2)if和else中的程式碼能同時被執行?
那麼呼叫這個fork函式時發生了什麼呢?fork函式建立了一個新的程式,新程式(子程式)與原有的程式(父程式)一模一樣。子程式和父程式使用相同的程式碼段;子程式拷貝了父程式的堆疊段和資料段。子程式一旦開始執行,它複製了父程式的一切資料,然後各自執行,相互之間沒有影響。
fork函式對返回值做了特別的處理,呼叫fork函式之後,在子程式中fork的返回值是0,在父程式中fork的返回是子程式的編號,程式設計師可以通過fork的返回值來區分父程式和子程式,然後再執行不同的程式碼。
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <unistd.h> void fatchfunc() // 父程式流程的主函式 { printf("我是老子,我喜歡孩子他娘。\n"); } void childfunc() // 子程式流程的主函式 { printf("我是兒子,我喜歡西施。\n"); } int main() { if (fork() > 0) { printf("這是父程式,將呼叫fatchfunc()。\n"); fatchfunc(); } else { printf("這是子程式,將呼叫childfunc()。\n"); childfunc(); } sleep(1); printf("父子程式執行完自己的函式後都來這裡。\n"); sleep(1); }
執行結果:
在上文上已提到過,子程式拷貝了父程式的堆疊段和資料段,也就是說,在父程式中定義的變數子程式中會複製一個副本,fork之後,子程式對變數的操作不會影響父程式,父程式對變數的操作也不會影響子程式。
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int i=10; int main() { int j=20; if (fork()>0) //從 fork() 這個函式開始出現後, //便建立了子程式並且和父程式一樣從fork() //這個函式一起執行下去,也就是說從fork()開始的下面所有程式碼分別被父///程式和子程式都執行了一次,如果沒有條件判斷語句判別fork()的返回/////值,將無法分別子父程式,根據fork()的返回值可以令子父程式跳過或執///行某條語句 { //如果fork大於零,證明是父程式,即執行下面的語句 i=11;j=1; sleep(1); printf("父程式:i=%d,j=%d\n",i,j); int sum = i + j; printf("父sum = %d\n",sum); } else { //如果fork小於零,證明是子程式,執行下面的語句 i=12;j=22; sleep(1); printf("子程式:i=%d,j=%d\n",i,j); printf("子sum = %d\n",i+j); } }
執行結果
作者:碼農有道
作業:
(1)編寫一個多程式程式,驗證子程式是複製父程式的記憶體變數,還是父子程式共享記憶體變數?
複製記憶體變數
2)編寫一個示例程式,由父程式生成10個子程式,在子程式中顯示它是第幾個子程式和子程式本身的程式編號。
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int i = 0; while (i < 10) { if (fork() > 0) { i++; continue; //父程式回到while(迴圈), } else { printf("子程式第%d個,pid = %d\n", i, getpid()); break; } } sleep(10); return 0; }
執行結果
3)編寫示例程式,由父程式生成子程式,子程式再生成孫程式,共生成第10代程式,在各級子程式中顯示它是第幾代子程式和子程式本身的程式編號。
如圖
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int i = 0; //全域性變數,計數器,計算第幾代子程式 while (i < 10) { if (fork()== 0) { i++; continue; } else { printf("第%d代子程式,pid = %d\n", i, getpid()); 第 0 代子程式是第一個父程式 break; } } sleep(10); return 0; }
執行結果:
子程式是下一個子程式的父程式
4)利用盡可能少的程式碼快速fork出更多的程式,試試看能不能把linux系統搞死。
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int i = 0; //全域性變數,計數器,計算第幾代子程式 while (i < 10) { if (fork()>0) { fork(); } } printf("pid=%d",getpid()); return 0; }
5)ps -ef |grep book251命令是ps和grep兩個系統命令的組合,各位查一下資料,瞭解一下grep命令的功能,對程式設計師來,grep是經常用到的命令。
https://blog.csdn.net/weixin_52273136/article/details/110451596
來源:C語言技術網(www.freecplus.net)
作者:碼農有道