程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Linux下C說話的fork()子過程函數用法及相干成績解析

Linux下C說話的fork()子過程函數用法及相干成績解析

編輯:關於C++

Linux下C說話的fork()子過程函數用法及相干成績解析。本站提示廣大學習愛好者:(Linux下C說話的fork()子過程函數用法及相干成績解析)文章只能為提供參考,不一定能成為您想要的結果。以下是Linux下C說話的fork()子過程函數用法及相干成績解析正文


fork
fork()函數是linux下的一個體系挪用,它的感化是發生一個子過程,子過程是以後過程的一個正本,它跟父過程有一樣的虛存內容,但也有一些分歧點。
然則,值得留意的是,父過程挪用fork()後,fork()前往的是生成的子過程(假如能順遂生成的話)的ID。子過程履行的終點也是代碼中fork的地位,分歧的是上面這段C說話代碼展現了fork()函數的應用辦法:

// myfork.c

#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv) {
  while (1) {
    pid_t pid = fork();
    if (pid > 0) {
      // 主過程
      sleep(5);
    } else if (pid == 0) {
      // 子過程
      return 0;
    } else {
      fprintf(stderr, "fork error\n");
      return 2;
    }
  }
}

挪用fork()函數後,體系會將以後過程的絕年夜部門資本拷貝一份(個中的copy-on-write技巧這裡不胪陳),該函數的前往值有三種情形,分離是:
1.年夜於0,表現以後過程為父過程,前往值是子過程號;
2.等於0,表現以後過程是子過程;
3.小於0(確實地說是等於-1),表現fork()挪用掉敗。

看兩個比擬成心思的C說話標題。
 
第一題:盤算上面代碼實際上總共打印了若干行:(網易2011口試題)

#include
#include
#include
int main(){
    int i;
    for(i = 0; i<5; i++){
        fork();
        printf("%d\n",getpid());
        fflush(stdout);
    }
}

成績解答:
這道成績其實不難,最快的設法主意就是2+4+8+16+32,由於第一層的printf會有兩個過程打印,第二層會增長到4個,以此往下,就得出62行。
 
但我這裡盤算采取別的一種辦法,一種加倍直不雅的辦法,就是直接數出來,如許會防止年夜腦短路,並且對下一標題有贊助。
 
要直接數出來也很簡略,只是有些繁瑣,由於每輪回一次,都邑打印一行而且發生一個子過程,子過程又會持續輪回打印並發生新的過程。我們可以在草稿紙上畫一棵樹,畫出每一個過程的子過程和輪回次數,假如你眼光夠好,頭腦不輕易亂,這類辦法很快會讓你獲得准確謎底。但我正好頭腦不是可以或許包管蘇醒的人,畫了三遍樹獲得的都是毛病謎底。
 
隨後,我在紙上用了一種更簡略的數據構造——隊列停止盤算,而且順遂得出了謎底。我是如許盤算的:

起首,主過程會輪回5次,則我們將5壓入到隊列中:

queue =" 5 ";
sum = 0; //sum是總打印次數

主過程會輪回5次,打印5行而且發生5個子過程,這5個子過程分離會打印5,4,3,2,1行,則我們將這5個數放入隊列,並將第一個5出隊列參加到sum中:

queue = " 5 4 3 2 1 ";
sum = sum + 5;

如許,我們再取隊列首元素,即5,他會打印5行,而且生成4個子過程,子過程的分離會打印4,3,2,1行,我們把這4個數放入到隊列中,並將第一個5出隊列參加到sum中:

queue = " 4 3 2 1 4 3 2 1";
sum = sum + 5;

我們持續反復下面的任務,取首元素4,他會打印4行,而且會宣稱3個子過程,子過程分離打印3,2,1行,反復下面的入隊列和出隊列操作:

queue = " 3 2 1 4 3 2 1 3 2 1 ";
sum = sum + 4;

如許,以此反復以上的操作,當碰到元素1的時刻,只要出隊列而沒有入隊列的操作,由於只打印1行的子過程不會再輪回發生新的子過程。最初,當隊列中不再有元素的時刻,sum就是總共打印的行數。
 
這類辦法的有點是你可以很輕松、很蘇醒的在紙上把隊列寫出來並算出謎底,缺陷是假如你加法欠好,很輕易算錯謎底!
 

第二題:問上面的代碼履行後總共發生了若干過程(不包含主過程)?(2009 EMC口試)

#include
int main(){
    fork();
    fork() && fork() || fork();
    fork();
}

這個標題跟上一個比較起來就略微有點難度了,由於你就算畫樹也有能夠算錯!
 
我小我感到這個標題考核兩方面的常識:1、開首所講的fork()前往值;2、&&和||的運算。
 
讓我們現評論辯論下&&和||的運算再來持續評論辯論這個標題。&&是“邏輯與”操作,假如兩個操作數有一個為0,則全部式子為0。尺度C中劃定,假如&&運算符的左操作數為0,則不盤算右操作數;假如左操作數為1,才盤算右操作數。
與之相似,||操作符是“邏輯或”操作,尺度C劃定假如||運算符左操作數為1,則不盤算右操作數;假如左操作數為0,則盤算右操作數。
 
持續來看我們的標題,我們把標題中的5個fork()分離標志為A,B,C,D,E。則我們可以看到,主過程一共發生4個過程,分離發生在A,B,C,E地位上(B,C兩個fork()前往值都不是0,是以B&&C不為0,是以不盤算D)。讓我們依然采取上題的算法,應用一個隊列:

起首,將主過程發生子過程的地位放到隊列中:

queue = " A B C E ";
sum = 0;

我們從隊列中取首元素A,我們剖析A處發生的過程,發明它會在B, C, E三處發生子過程,我們把這三個元素拔出到隊列中,並將sum+1。

queue = " B C E B C E ";
sum ++;

然後,我們從隊列中掏出首元素B,B處發生的子過程稍略不一樣,由於子過程中B所代表的fork()前往值為0,是以C得不到履行,而D會獲得履行。是以,B處發生的子過程會履行D, E,將這兩個元素送入隊列,sum++:

queue = " C E B C E D E ";
sum ++;

上面,我們取首元素C,剖析發明,C處發生的過程會履行D, E,送入隊列而且sum++:

queue = " E B C E D E D E ";
sum ++;

同上一題一樣,順次如許履行,碰到E則沒有元素入隊列,直到最初隊列為空,sum就是總共發生的過程個數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved