fork()和wait()方法有两个子进程 [英] fork() and wait() with two child processes

查看:173
本文介绍了fork()和wait()方法有两个子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用叉()和wait()函数来完成一项任务。我们正在建模不确定性的行为和需要的程序叉()如果有一个以上的可能的过渡。

为了试图解决如何叉和等待工作,我刚刚作出了一个简单的程序。我想我现在的电话是如何工作的,并会被罚款,如果该程序只支一次,因为父进程可以使用退出状态从单一的子进程来确定子进程是否达到接受状态还是不明白。

你可以从下面虽然code看到的,我希望能够处理的地方,必须有一个以上的子进程的情况。我的问题是,你似乎只能够设置使用_exit函数后的状态。所以,在我的例子,对于节目的父进程测试,第一个孩子进程发出0作为它的退出状态,但对第二个孩子过程中没有信息的退出状态。

我试过根本就不是_exit() - ING在拒绝,但后来发现孩子进程将继续,并在那里效力似乎是两个父进程

对不起,华夫饼干,但我将不胜感激,如果有人可以告诉我,我的父进程如何获得一个以上的孩子过程中的状态信息,或者我会很乐意父进程只通知接受状态的子进程,但在这种情况下,我会成功需要从其中有一个拒绝状态子进程退出。

我的测试code是如下:

 的#include<&stdio.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&errno.h中GT;
#包括LT&; SYS / wait.h>诠释主要(无效){    将为pid_t child_pid,wpid,PID;
    INT状态= 0;
    INT I;    诠释一个[3] = {1,2,1};
    为(ⅰ= 1; I&下; 3;我++){
        输出(I =%d个\\ N,I);
        PID = GETPID();
        的printf(,PID后,我=%d个\\ n PID);
        如果((child_pid =叉())== 0){
            的printf(在子进程\\ n);
            PID = GETPID();
            的printf(PID的子进程为%d \\ n,PID);
            / *是一个子进程* /
            如果(一个由[i] 2){
                的printf(应该是接受\\ n);
                _exit(1);
            }其他{
                的printf(应该拒绝\\ n);
                _exit(0);
            }
        }
    }    如果(child_pid大于0){
        / *是父进程* /
        PID = GETPID();
        的printf(parent_pid =%d个\\ N,PID);
        wpid =等待(安培;状态);
        如果(wpid!= -1){
            的printf(孩子的退出状态是%d个\\ N,地位);
            如果(状态> 0){
                的printf(接受\\ n);
            }其他{
                的printf(完整父进程\\ n);
                如果(一个[0] 2){
                    的printf(接受\\ n);
                }其他{
                    的printf(拒绝\\ n);
                }
            }
        }
    }
    返回0;
}


解决方案

在我看来好像根本的问题是,你有一个等待()通话,而不是一个循环,等待,直到有没有更多的孩子。如果最后叉()是成功的,而不是当至少有一个叉()成功也只能等待。

您应该只使用 _exit()如果您不希望正常清理操作 - 如冲洗打开的文件流,包括标准输出。有场合下使用 _exit();这是不是其中之一。 (在这个例子中,你也可以的,当然,只要有孩子恢复,而不是调用退出()直接因为返回主()等价于返回的状态退出。然而,大多数时候你会做的分叉和比主要功能等(),然后退出()往往是合适的。)


黑客攻击,你的code的简化版本,给我想要的诊断。请注意,您跳过循环数组的第​​一个元素(我没有)。

 的#include<&stdio.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&; SYS / wait.h>INT主要(无效)
{
    将为pid_t child_pid,wpid;
    INT状态= 0;
    INT I;
    诠释一个[3] = {1,2,1};    的printf(parent_pid =%d个\\ N,GETPID());
    对于(I = 0; I&下; 3;我+ +)
    {
        输出(I =%d个\\ N,I);
        如果((child_pid =叉())== 0)
        {
            的printf(在子进程(PID =%d)\\ n,GETPID());
            如果(一个由[i] 2)
            {
                的printf(应该是接受\\ n);
                出口(1);
            }
            其他
            {
                的printf(应该拒绝\\ n);
                出口(0);
            }
            /*还没到*/
        }
    }    而((wpid =等待(安培;状态))0)
    {
        的printf(%d个的退出状态是%D(%S)\\ n,(INT)wpid,地位,
               (状态> 0)? 接受:拒绝);
    }
    返回0;
}

输出示例(MacOS X的10.6.3):

  parent_pid = 15820
I = 0
I = 1
在子进程(PID = 15821)
应接受
设为i = 2
在子进程(PID = 15822)
应拒收
在子进程(PID = 15823)
应接受
的15823退出状态是256(接受)
的15822退出状态为0(拒绝)
的15821退出状态是256(接受)

I need to use the fork() and wait() functions to complete an assignment. We are modelling non-deterministic behaviour and need the program to fork() if there is more than one possible transition.

In order to try and work out how fork and wait work, I have just made a simple program. I think I understand now how the calls work and would be fine if the program only branched once because the parent process could use the exit status from the single child process to determine whether the child process reached the accept state or not.

As you can see from the code that follows though, I want to be able to handle situations where there must be more than one child processes. My problem is that you seem to only be able to set the status using an _exit function once. So, as in my example the exit status that the parent process tests for shows that the first child process issued 0 as it's exit status, but has no information on the second child process.

I tried simply not _exit()-ing on a reject, but then that child process would carry on, and in effect there would seem to be two parent processes.

Sorry for the waffle, but I would be grateful if someone could tell me how my parent process could obtain the status information on more than one child process, or I would be happy for the parent process to only notice accept status's from the child processes, but in that case I would successfully need to exit from the child processes which have a reject status.

My test code is as follows:

#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;
}

解决方案

It looks to me as though the basic problem is that you have one wait() call rather than a loop that waits until there are no more children. You also only wait if the last fork() is successful rather than if at least one fork() is successful.

You should only use _exit() if you don't want normal cleanup operations - such as flushing open file streams including stdout. There are occasions to use _exit(); this is not one of them. (In this example, you could also, of course, simply have the children return instead of calling exit() directly because returning from main() is equivalent to exiting with the returned status. However, most often you would be doing the forking and so on in a function other than main(), and then exit() is often appropriate.)


Hacked, simplified version of your code that gives the diagnostics I'd want. Note that your for loop skipped the first element of the array (mine doesn't).

#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;
}

Example output (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)

这篇关于fork()和wait()方法有两个子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆