代码之家  ›  专栏  ›  技术社区  ›  TheShield

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

  •  1
  • TheShield  · 技术社区  · 7 年前

    我有一个从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
    

    父母和 仅从整个程序的单个fork调用派生的子进程。这可能吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   dbush    7 年前

    在您的孩子部分:

    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);
            }           
        }
        ...
    

    仅有一个的 值,将其发送给父级,然后等待父级的结果。同时,父节点已经从子节点读取了第一个值,并且正在等待另一个值,因此父节点和子节点处于死锁状态,等待另一个节点向它们发送内容。

    您希望子对象循环读取值,直到得到-1, 然后 等待家长。

        if (pidVal == 0) {
            printf("Child Process (should be 0): %d\n", pidVal);
            do {
                val = getInput();
                printf("You typed: %d\n", val);
                //Write to parent
                close(fd[0]);
                write(fd[1], &val, sizeof(val));
            } while (val != -1);
            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);
            }
        }