0

我目前正在编写一个简单的 C 程序来从父进程创建指定数量的子进程,并且我试图通过每次增加变量active来跟踪其中有多少子进程实际上成功启动了一个孩子-进程成功。

但是,#!%€ 变量的愚蠢部分不允许我修改它。我是 C 的新手(因此程序的简单性和有问题的可用性),我在理解不同之处时遇到了一些问题变量范围以及何时以及如何修改它们以使新值保持不变...

所以,我的问题是;如何使变量“活动”增加 1?

我已经确保 newChild() 函数按应有的方式返回 1,并且该 if 语句中的其他代码有效,所以不是这样。而且,我也尝试过使用指针,但没有成功...... :(

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

main()
{
    printf("Parent CREATED\nRunning code...\n");

    // INITIATE Variables
    int children = 5;
    int active = 0;
    int parentID = getpid();

    // INITIATE Random Seed
    srand(time(NULL));

    // CREATE Children
    int i, cpid, sleepTime;

    for (i = 0; i < children; i++)
    {
        // Only let the parent process create new children
        if (getpid() == parentID)
        {
            // GET Random Number
            sleepTime = rand() % 10;

            // CREATE Child
            if (newChild(sleepTime) == 1)
            {
                // Mark as an active child process
                active++;
            }
        }
    }

    // CLEAN UP
    if (getpid() == parentID)
    {
        // Let the parent process sleep for a while...
        printf("Parent is now SLEEPING for 20 seconds...\n");
        sleep(20);
        printf("Parent is now AWAKE\nActive children: %d\n", active);

        // WAIT for Children
        int cpid, i;
        int status = 0;

        for (i = 0; i < active; i++)
        {
            // WAIT for Child
            cpid = wait(&status);

            // OUTPUT Status
            printf("WAITED for Child\nID: %d, Exit Status: %d\n", cpid, status);
        }

        printf("All children are accounted for.\nEXITING program...\n");
    }
}

int newChild(int sleepTime)
{
    // INITIATE Variable
    int successful = 0;

    // CREATE Child Process
    int pid = fork();

    if (pid == -1)
    {
        // OUTPUT Error Message
        printf("The child process could not be initiated.");
    }
    else if (pid == 0)
    {
        // Mark child process as successfully initiated
        successful = 1;

        // OUTPUT Child Information
        printf("Child CREATED\nID: %d, Parent ID: %d, Group: %d\n", getpid(), getppid(), getpgrp());

        // Let the child process sleep for a while...
        printf("Child %d is now SLEEPING for %d seconds...\n", getpid(), sleepTime);
        sleep(sleepTime);
        printf("Child %d is now AWAKE\n", getpid());
    }

    return successful;
}
4

1 回答 1

1

调用 fork() 会产生三种结果,您的代码错误地将其压缩为两种:

  1. 返回值 -1 表示分叉失败。这是一种不常见的错误情况。
  2. 返回值 0 表示 fork 成功并且您现在处于子进程中。
  3. 返回值 >0 表示 fork 成功并且您在父进程中。

请注意案例 2 和案例 3 是如何“成功”的。但是您的 newChild() 函数为案例 2 返回 1,为案例 3 返回 0。相反,它应该为案例 3 返回 1,而对于案例 2,它甚至不应该 return。如果你是情况 2,那么你就在子进程中,所以你应该只做你的子进程的东西然后退出,永远不要返回给调用者。

if (pid == -1)
{
    // OUTPUT Error Message
    printf("The child process could not be initiated.");
}
else if (pid == 0)
{
    // OUTPUT Child Information
    printf("Child CREATED\nID: %d, Parent ID: %d, Group: %d\n", getpid(), getppid(), getpgrp());

    // Let the child process sleep for a while...
    printf("Child %d is now SLEEPING for %d seconds...\n", getpid(), sleepTime);
    sleep(sleepTime);
    printf("Child %d is now AWAKE\n", getpid());

    // This is the child process, so we should NOT EVEN RETURN from newChild().
    exit(0);
}
else
{
    successful = 1;
}

这里的关键观察是,当您调用 fork() 时,您的进程将分成两个独立的进程,这两个进程都从 fork() 返回的点继续执行。它们之间的区别在于,一个将获得 0 返回值,而另一个将获得 >0 返回值。前者是孩子,后者是父母。

在 fork() 之后,您现在运行了相同代码的两个副本,两个单独的 newChild() 调用正在运行,并且具有两个单独的active变量副本。分叉后有两个。

于 2013-03-13T21:46:32.857 回答