从另一个块中增加变量

时间:2013-03-13 21:29:39

标签: c fork scope

我正在编写一个简单的C程序来从父进程创建指定数量的子进程,我正在尝试通过增加变量

然而,#!%€变量的愚蠢的部分不会让我修改它..我是C的新手(因此程序的简单性和可疑性)并且我遇到了一些问题理解不同的变量范围以及何时以及如何修改它们以使新值坚持......

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

我已经确定newChild()函数应该返回1,而if-statement中的其他代码也可以工作,所以不是这样。而且,我也试过使用指针,但没有成功...... :(

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

1 个答案:

答案 0 :(得分:1)

调用fork()有三个结果,你的代码错误地缩减为两个:

  1. 返回值-1表示fork失败。这是一种不常见的错误情况。
  2. 返回值为0表示fork已成功,您现在处于子进程中。
  3. 返回值> 0表示fork已成功,您在父进程中。
  4. 注意案例2和3是如何“成功”的。但是对于案例2,你的newChild()函数返回1,而对案例3返回0。相反,它应该做的是为案例3返回1,对于案例2,甚至不应该返回。如果你在案例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变量的两个独立副本。分叉后,有两件事。