簡體   English   中英

fork()和wait()有兩個子進程

[英]fork() and wait() with two child processes

我需要使用fork()和wait()函數來完成賦值。 我們正在對非確定性行為進行建模,如果存在多個可能的轉換,則需要fork()程序。

為了嘗試解決fork和wait如何工作,我剛剛制作了一個簡單的程序。 我想現在我理解調用是如何工作的,並且如果程序只分支一次會很好,因為父進程可以使用單個子進程的退出狀態來確定子進程是否達到接受狀態。

從下面的代碼中可以看出,我希望能夠處理必須有多個子進程的情況。 我的問題是你似乎只能使用_exit函數設置狀態一次。 因此,在我的示例中,父進程測試的退出狀態顯示第一個子進程在其退出狀態時發出0,但沒有關於第二個子進程的信息。

我試着簡單地不是_exit() - 拒絕,但那個子進程會繼續,實際上似乎有兩個父進程。

對於華夫餅干感到抱歉,但如果有人能告訴我父進程如何獲取有關多個子進程的狀態信息,我將不勝感激,或者我很高興父進程只能注意到來自子進程的接受狀態,但在這種情況下,我將成功地需要退出具有拒絕狀態的子進程。

我的測試代碼如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>

int main(void)  {

    pid_t child_pid, wpid, pid;
    int status = 0;
    int i;

    int a[3] = {1, 2, 1};
    for(i = 1; i < 3; i++)  {
        printf("i = %d\n", i);
        pid = getpid();
        printf("pid after i = %d\n", pid);
        if((child_pid = fork()) == 0)  {
            printf("In child process\n");
            pid = getpid();
            printf("pid in child process is %d\n", pid);
            /* Is a child process */
            if(a[i] < 2)  {
                printf("Should be accept\n");
                _exit(1);
            } else  {
                printf("Should be reject\n");
                _exit(0);
            }
        }
    }

    if(child_pid > 0)  {
        /* Is the parent process */
        pid = getpid();
        printf("parent_pid = %d\n", pid);
        wpid = wait(&status);
        if(wpid != -1)  {
            printf("Child's exit status was %d\n", status);
            if(status > 0)  {
                printf("Accept\n");
            } else  {
                printf("Complete parent process\n");
                if(a[0] < 2)  {
                    printf("Accept\n");
                } else  {
                    printf("Reject\n");
                }
            }
        }
    }
    return 0;
}

它看起來好像基本的問題是你有一個wait()調用,而不是一個等待,直到沒有更多的孩子。 您也只能等待最后一個fork()成功,而不是至少有一個fork()成功。

如果您不想進行正常的清理操作,則應該只使用_exit() - 例如刷新包含stdout打開文件流。 有時候使用_exit() ; 這不是其中的一個。 (在這個例子中,你當然也可以直接讓孩子返回而不是直接調用exit() ,因為從main()返回相當於退出返回狀態。但是,大多數時候你會做分叉和在main()以外的函數中等等,然后exit()通常是合適的。)


黑客,簡化版本的代碼,提供我想要的診斷。 請注意,你的for循環跳過了數組的第一個元素(我的沒有)。

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

int main(void)
{
    pid_t child_pid, wpid;
    int status = 0;
    int i;
    int a[3] = {1, 2, 1};

    printf("parent_pid = %d\n", getpid());
    for (i = 0; i < 3; i++)
    {
        printf("i = %d\n", i);
        if ((child_pid = fork()) == 0)
        {
            printf("In child process (pid = %d)\n", getpid());
            if (a[i] < 2)
            {
                printf("Should be accept\n");
                exit(1);
            }
            else
            {
                printf("Should be reject\n");
                exit(0);
            }
            /*NOTREACHED*/
        }
    }

    while ((wpid = wait(&status)) > 0)
    {
        printf("Exit status of %d was %d (%s)\n", (int)wpid, status,
               (status > 0) ? "accept" : "reject");
    }
    return 0;
}

示例輸出(MacOS X 10.6.3):

parent_pid = 15820
i = 0
i = 1
In child process (pid = 15821)
Should be accept
i = 2
In child process (pid = 15822)
Should be reject
In child process (pid = 15823)
Should be accept
Exit status of 15823 was 256 (accept)
Exit status of 15822 was 0 (reject)
Exit status of 15821 was 256 (accept)

將wait()函數放在循環中並等待所有子進程。 如果沒有更多的子進程可用,則wait函數將返回-1並且errno將等於ECHILD。

精彩的例子Jonathan Leffler,為了讓你的代碼在SLES上運行,我需要添加一個額外的頭來允許pid_t對象:)

#include <sys/types.h>

暫無
暫無

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

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