簡體   English   中英

我正在嘗試在 C 中制作 fork() 進程調用的圖表

[英]I'm trying to make a diagram of fork() process calls in C

這就是我現在的位置

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

main(){   
    int n;
    int i;
    int x = 1;

    printf("\nenter number of forks:\n");
    scanf ("%d",&n);
    printf("\nnow forking %d times....\n\n", n);

    for (i = 1;i <= n; i++){
        int pid = fork();
        if (pid < 0){ 
            return -1;
        }

        if (pid != 0){
            printf("\nI am the parent (
                ppid = %d pid = %d)\n",getppid(),getpid()
            );          
            printf(" x = %d\n",x);

            x++;
            wait();
        }else{
            printf("\nI am the child (
                ppid = %d, pid = %d)\n x = 
                %d\n-------------------------------\n",
                getppid(),getpid(),x
            );
        }
    }
}

這是我傳入 4 時的輸出:

enter number of forks:
4

now forking 4 times....


I am the parent (ppid = 26178 pid = 39785)
 x = 1

I am the child (ppid = 39785, pid = 39786)
 x = 1
-------------------------------

I am the parent (ppid = 39785 pid = 39786)
 x = 1

I am the child (ppid = 39786, pid = 39787)
 x = 1
-------------------------------

I am the parent (ppid = 39786 pid = 39787)
 x = 1

I am the child (ppid = 39787, pid = 39788)
 x = 1
-------------------------------

I am the parent (ppid = 39787 pid = 39788)
 x = 1

I am the child (ppid = 39788, pid = 39789)
 x = 1
-------------------------------

I am the parent (ppid = 39786 pid = 39787)
 x = 2

I am the child (ppid = 39787, pid = 39790)
 x = 2
-------------------------------

I am the parent (ppid = 39785 pid = 39786)
 x = 2

I am the child (ppid = 39786, pid = 39791)
 x = 2
-------------------------------

I am the parent (ppid = 39786 pid = 39791)
 x = 2

I am the child (ppid = 39791, pid = 39792)
 x = 2
-------------------------------

I am the parent (ppid = 39785 pid = 39786)
 x = 3

I am the child (ppid = 39786, pid = 39793)
 x = 3
-------------------------------

I am the parent (ppid = 26178 pid = 39785)
 x = 2

I am the child (ppid = 39785, pid = 39794)
 x = 2
-------------------------------

I am the parent (ppid = 39785 pid = 39794)
 x = 2

I am the child (ppid = 39794, pid = 39795)
 x = 2
-------------------------------

I am the parent (ppid = 39794 pid = 39795)
 x = 2

I am the child (ppid = 39795, pid = 39796)
 x = 2
-------------------------------

I am the parent (ppid = 39785 pid = 39794)
 x = 3

I am the child (ppid = 39794, pid = 39797)
 x = 3
-------------------------------

I am the parent (ppid = 26178 pid = 39785)
 x = 3

I am the child (ppid = 39785, pid = 39798)
 x = 3
-------------------------------

I am the parent (ppid = 39785 pid = 39798)
 x = 3

I am the child (ppid = 39798, pid = 39799)
 x = 3
-------------------------------

I am the parent (ppid = 26178 pid = 39785)
 x = 4

I am the child (ppid = 39785, pid = 39800)
 x = 4
-------------------------------

我注意到的第一件事是,對於代碼運行的每個實例,“子”的 PPID 是“父”的 PID,所以很好。

但是當我手工繪制圖表時:我的輸出圖表(我是新手,所以我不能發布照片)

為了分配,它應該是一個平衡的樹,以便級別的想法很重要。 我希望將每個進程打印為圖表中的一個節點,例如我使用 graphviz 繪制的,並且每個節點都應包括其 PID 和其級別。

這是 Geeks for Geeks 的一個例子,展示了我所說的級別的含義:


       L1       // There will be 1 child process 
    /     \     // created by line 1.
  L2      L2    // There will be 2 child processes
 /  \    /  \   //  created by line 2
L3  L3  L3  L3  // There will be 4 child processes 
                // created by line 3

我想我過度編碼了這個。 我應該如何更改我的代碼以在循環中分叉並獲得樹狀結構? 我正在嘗試使用變量 x 來表示級別,但我不確定它是否有效,因為輸出的結構對我來說非常出乎意料。

你的直覺有問題。 在循環的每次迭代期間,您的所有進程都將派生並創建一個新進程 - 不僅僅是在上一次迭代中創建的進程。

因此,通過 4 次迭代,您希望初始過程以四個孩子結束:

  • 一個有 3 個孩子(圖中 55 個)
  • 一個有 2 個孩子(圖中 63 個)
  • 一個有 1 個孩子(圖中 67 個);
  • 一個沒有孩子(你的圖中是 69)

這正是你最終得到的。 如果您對每個子項都遵循相同的邏輯並適當減少剩余循環迭代次數,您將完全重現您擁有的圖表。

這個問題不是完全重復,但涵蓋了大部分相同的領域。

你的圖當然是一棵樹——它只是不是一個完全平衡的二叉樹。 要獲得這樣的結果,您必須在每次循環迭代期間按照以下方式做更多的事情:

  1. fork 進程兩次
  2. 在每個孩子中,立即繼續下一次循環迭代(這樣他們都不會在下一次迭代之前再次分叉)
  3. 在父級中,分叉后完全脫離循環,這樣它就不會再次分叉

例如:

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

int main(void) {
    int level;

    for ( level = 1; level <= 3; level++ ) {
        pid_t pids[2];

        pids[0] = fork();
        if ( pids[0] == -1 ) {
            perror("fork failed");
            exit(EXIT_FAILURE);
        } else if ( pids[0] == 0 ) {
            continue;
        }

        pids[1] = fork();
        if ( pids[1] == -1 ) {
            perror("fork failed");
            exit(EXIT_FAILURE);
        } else if ( pids[1] == 0 ) {
            continue;
        }

        for ( int i = 0; i < 2; i++ ) {
            if ( waitpid(pids[i], NULL, 0) == -1 ) {
                perror("waitpid failed");
                exit(EXIT_FAILURE);
            }
        }

        break;
    }

    printf("level %d: parent %ld, child %ld\n", level, (long) getppid(), (long) getpid());

    return 0;
}

帶有輸出,顯示您完全平衡的二叉樹:

me@mac:$ ./fork | sort
level 1: parent 62427, child 73103
level 2: parent 73103, child 73105
level 2: parent 73103, child 73106
level 3: parent 73105, child 73107
level 3: parent 73105, child 73109
level 3: parent 73106, child 73108
level 3: parent 73106, child 73111
level 4: parent 73107, child 73110
level 4: parent 73107, child 73114
level 4: parent 73108, child 73112
level 4: parent 73108, child 73116
level 4: parent 73109, child 73113
level 4: parent 73109, child 73117
level 4: parent 73111, child 73115
level 4: parent 73111, child 73118

暫無
暫無

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

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