如何通过单个fork()调用使子进程保持活动状态?

时间:2019-02-06 15:16:56

标签: c fork

我有一个程序可以通过fork()调用创建子进程。子级将连续从用户接收1字节整数输入。一旦将整数发送给子代,子代将使用管道将值发送给父代。当父对象收到该值时,它将把它添加到数组中。 -1发送结束程序。子级向父级发送-1后,父级将对数组中的先前值求和,并使用另一个管道将该总和值发送给子级,子级将在该子级中打印该值并终止程序。

到目前为止,这是我的代码:

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

//Gets input from the user
int getInput() {
    int val; char temp;
    scanf("%hhd", &temp);
    val = temp;
    return val;
}

//Sums the values of the entered numbers and returns it
int finish(int arr[], int i) {
    int sum = 0;
    for (int j = 0; j < i; j++) {sum+= arr[j];}
    return(sum);
}

int main() {

    int fd[2], fd2[2], val = 0, i = 0, sum, final = -9999999;
    int arr[1000];
    pid_t pidVal;

    //Pipe for sending numbers from child to parent
    pipe(fd);

    //Pipe for sending the final sum from parent to child
    pipe(fd2);

    //Create parent and child processes
    pidVal = fork();

    //Used to make it run continously until -1 is pressed
    while(1) {

        //Child Process
        if (pidVal == 0) {
            printf("Child Process (should be 0): %d\n", pidVal);
            val = getInput();
            printf("You typed: %d\n", val);
            //Write to parent
            close(fd[0]);
            write(fd[1], &val, sizeof(val));
            //Read if parent sends sum yet
            close(fd2[1]);
            read(fd2[0], &final, sizeof(final));
            //If sum sent from parent, print and terminate
            if (final != -9999999) {
                printf("%d\n", final);
                exit(0);
            }           
        }

        //Parent Process
        if (pidVal > 0) {
            printf("I'm the parent (should be > 0): %d\n", pidVal);
            //Read what child sent to the pipe
            close(fd[1]);
            read(fd[0], &val, sizeof(val));
            //If exit value recieved
            if (val == -1) {
                //Sum the numbers sent
                sum = finish(arr, i);
                //Close read directory
                close(fd2[0]);
                //Write the sum to the pipe
                write(fd2[1], &sum, sizeof(sum));
            } 

            //Not -1 as input
            else {
                //Collect input
                arr[i] = val;
                i++;
            }
        }
    }
}

但是问题是,当我尝试发送多个号码时,程序被卡住了,如以下示例输出所示:

I'm the parent (should be > 0): 5673
Child Process (should be 0): 0
3 //My Input
You typed: 3
I'm the parent (should be > 0): 5673
1 //My Input
2 //My Input

我注意到子进程似乎在第二次迭代中似乎没有执行,而父进程却执行了,这使我相信子进程在第一次运行后就终止了。在用户输入-1之前,如何保持这个孩子的生命?更重要的是,我想仅通过整个程序的单个fork调用派生的一个父进程和一个子进程来实现此功能。这可能吗?

1 个答案:

答案 0 :(得分:2)

在您的孩子部分:

unsigned int a = UINT_MAX;
a++;

您正在从用户读取单个值,然后将其发送给父级,然后等待父级的结果。同时,父级已从子级中读取第一个值,并正在等待另一个值,因此父级和子级处于死锁状态,等待另一个给他们发送东西。

您希望孩子循环读取值直到它变成-1,然后然后等待父母。

while(1) {

    if (pidVal == 0) {
        printf("Child Process (should be 0): %d\n", pidVal);
        val = getInput();
        printf("You typed: %d\n", val);
        //Write to parent
        close(fd[0]);
        write(fd[1], &val, sizeof(val));
        //Read if parent sends sum yet
        close(fd2[1]);
        read(fd2[0], &final, sizeof(final));
        //If sum sent from parent, print and terminate
        if (final != -9999999) {
            printf("%d\n", final);
            exit(0);
        }           
    }
    ...