簡體   English   中英

當 fork() 處於某個條件時會發生什么?

[英]What happens when fork() in a condition?

誰能給我這個代碼的輸出(有解釋)? 謝謝...

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

int main() 
{ 
    if (fork() && (!fork())) { 
        if (fork() || fork()) {
            fork(); 
        } 
    } 
    printf("Friend\n");
    return 0; 
}

在進入代碼之前最好先了解什么是 fork() 系統調用

fork() 系統調用由“父”創建一個新進程,新創建的進程稱為“子”進程

當fork成功時,子進程返回0,父進程返回正整數

這就是這里的線索

因此,從該程序計數器開始,所有兩個進程都同時工作......

在這里 fork() 處於 if 條件,並且在猜測輸出時也有點棘手

  1. 首先 fork() 創建新的 C1 -> 0

  2. 第二個 fork() 創建新的 C2 -> !0 -> 1

所以第一個條件由 C2(其父正整數和 c2 為 0)統計,但未由父或子 C1 統計,因此其他分叉將不起作用

然后 C2 進入另一個 if 條件並制作另外兩個叉子

            C2
          /    \
         C2     C3
       /   \   /  \
      C2   c4  c3  c5

然后所有創建的進程(包括父進程)打印“朋友”輸出 7 次

快速回答是父母會做某事,而孩子會做其他事情。 但是繼續閱讀……

好吧,我只是稍微修改了您的代碼,您將從程序的輸出中獲得所有進程層次結構,以及您問題的答案:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h> 

static pid_t my_fork() /* tracing is your friend! :) */
{
    pid_t chld = fork();
    if (chld > 0) {
        /* only the parent shows this */
        printf("[pid=%d, child=%d] forked!\n",
                getpid(), chld);
    }
    return chld;
}

int main() 
{ 
    /* print our pid, so we know the root of the hierarchy */
    printf("[pid=%d] Hello, world\n", getpid());

    /* do the embarrasing work */
    if (my_fork() && (!my_fork())) { 
        if (my_fork() || my_fork()) {
            my_fork(); 
        } 
    } 

    pid_t pid;
    int status;

    /* We do wait(2)'s while there are children to be waited for. 
     * it's a good thing to wait for children before ending. */
    while((pid = wait(&status)) >= 0) {
        printf("[pid=%d, child=%d]: child ended with status=%d\n",
                getpid(), pid, status);
    }
    
    /* we print the message when no more children are alive */
    printf("[pid=%d]: Hello friend!\n", getpid());

    return 0; 
}

這會產生

$ pru
[pid=72699] Hello, world
[pid=72699, child=72700] forked!
[pid=72699, child=72701] forked!
[pid=72700]: Hello friend!
[pid=72701, child=72702] forked!
[pid=72703]: Hello friend!
[pid=72699, child=72700]: child ended with status=0
[pid=72702, child=72703] forked!
[pid=72702, child=72705] forked!
[pid=72702, child=72703]: child ended with status=0
[pid=72705]: Hello friend!
[pid=72704]: Hello friend!
[pid=72701, child=72704] forked!
[pid=72701, child=72704]: child ended with status=0
[pid=72702, child=72705]: child ended with status=0
[pid=72702]: Hello friend!
[pid=72701, child=72702]: child ended with status=0
[pid=72701]: Hello friend!
[pid=72699, child=72701]: child ended with status=0
[pid=72699]: Hello friend!

這是層次結構:

[pid=72699] (says Hello, world, just starting)
  +-[pid=72700] (created in first fork() call of pid=72699)
  `-[pid=72701] (created in second fork() call of pid=72699)
     +-[pid=72702] (created in third fork() call of pid=72701)
     |  +-[pid=72703] (created in fourth fork() call of pid=72702)
     |  `-[pid=72705] (created in fifth fork() call of pid=72702)
     `-[pid=7204] (created in fourth fork() call of pid=72701)

(當然,如果進程用完了,層次會不一樣, fork(2)因為系統資源不足而失敗)

最后,您可能會擔心為什么消息

[pid=72703]: Hello friend!

出現在消息之前

[pid=72702, child=72703] forked!

但這就是多任務處理的奇妙世界。 fork(2)返回后打印消息,因此兩條消息由不同的進程打印,因此,它們可以按任何順序進行調度,因此子進程在父進程有機會打印誰是他的孩子。 這是完全正常的。

筆記

您必須注意fork()在出錯時返回-1 ,它在布爾測試中評估為true ,就像父級的結果一樣。 因此,如果您自由地將fork(2)的返回代碼用於布爾表達式,則父級將收到truefork()失敗時發生的任何錯誤(好吧,它們很少,但它們在加載的系統上是可能的)。 只需保存fork()的結果代碼並首先檢查錯誤,然后您就可以隨意使用任何您想要的布爾表達式。

上面的源代碼可以在這里下載

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM