在子进程完成该FIFO的写入之后,父进程如何读取FIFO? [英] How does a parent process read a FIFO after the child process finished the writing that FIFO?

查看:146
本文介绍了在子进程完成该FIFO的写入之后,父进程如何读取FIFO?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的基本程序,它有两个进程,第一个是parent,第二个是child.

I have a very simple basic program that has two process first one is parent and second one is child.

子进程应向FIFO中写入一些内容.在所有写作业完成之后(终止孩子之后). 然后,父进程应读取所有FIFO文件并打印到stdout.

Child process should write some stuff to the FIFO. After all writing jobs finished(after the child is terminated). Then parent process should read all the FIFO file and print to the stdout.

所以我认为,我需要wait(NULL);作为parent.因此,parent将等待直到child终止.但是child也由于写操作而被阻止,并且在读取此写操作时被阻止.因此,这两个过程相互等待,我认为这会发生死锁.

So I think, I need a wait(NULL); for parent. So the parent will wait until the child is terminated. But child is also blocked because of the writing and blocked for reading this writes. So both process wait each other and I think,there occur an deadlock.

我的程序是这样的:

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

int writeSomeStuffToFifo ();
void printAllFifo ();

char * myfifo = "myfifo";

int main(int argc, char **argv) { 

    int pid=0;
    int childPid=-1;
    int status;
    pid=fork();


    if ((pid = fork()) < 0){
        perror("fork() error");
    }
    else if (pid == 0) {
        writeSomeStuffToFifo ();
        exit(1);
    }
    else do {
        if ((pid = waitpid(pid, &status, WNOHANG)) == -1)
           perror("wait() error");
        else if (pid == 0) {
            //child running
            printf("child running\n");
        }
        else {
            if (WIFEXITED(status)){
                printf("child is terminated\n");
                printAllFifo();
            }
            else{ 
                printf("child did not exit successfully\n");
            }
        }
    } while (pid == 0);


    return 0;
}


int writeSomeStuffToFifo (){   //child process will run this function
    int fd;
    mkfifo(myfifo, 0666); 

    fd = open(myfifo, O_WRONLY);
    write(fd,"foo1\n",strlen("foo1\n"));
    close(fd);

    fd = open(myfifo, O_WRONLY);
    write(fd,"foo2\n",strlen("foo2\n"));
    close(fd);

    fd = open(myfifo, O_WRONLY);
    write(fd,"foo3\n",strlen("foo3\n"));
    close(fd);
}


void printAllFifo (){     //parent process will run this function
    int fd=open(myfifo, O_RDONLY);
    char* readBuffer=(char*)malloc((strlen("foo1\n")+strlen("foo2\n")+strlen("foo3\n"))*sizeof(char));
    read(fd, readBuffer, strlen("foo1\n")+strlen("foo2\n")+strlen("foo3\n"));
    printf("%s\n",readBuffer );
    close(fd);
}

推荐答案

mkfifo()创建一个有限大小的管道.您不应该在父进程中等待直到子进程完成才能阅读,而应该在父进程中不断阅读,同时检查子进程是否已经终止.

mkfifo() creates a pipe of limited size. You should not wait in the parent process until the child has finished in order to read, you should read constantly in the parent process while checking if the child has terminated already.

您可以使用ulimit -p来读取Linux系统中管道的默认大小.该数字是512的乘积,因此8的值表示4096个字节.

You can use ulimit -p in order to read the default size of pipes in your linux system. The number is multiplications of 512, so a value of 8 means 4096 bytes.

使用pipe()mkfifo()更适合该任务,因为您实际上不需要命名管道.这将为您提供2个fds,一个用于读取,另一个用于写入.在父代码中,关闭写入fd,在子代码中,关闭读取fd,然后可以从父代码中的管道开始读取,直到它返回值< =0.这意味着子进程具有终止(并且管道已关闭以进行写入).那么您只需从父代码中调用waitpid()来收集终止的子进程.

Using pipe() is more suited to the task than mkfifo() because you do not actually need a named pipe. this will provide you with 2 fds, one for read and one for write. In the parent code you close the write fd, in the child code you close the read fd, then you can start reading from the pipe in the parent code until it returns a value <= 0. This would mean that the child process has terminated (and the pipe was closed for writing). then you only need to call waitpid() from the parent code to collect the terminated child process.

这篇关于在子进程完成该FIFO的写入之后,父进程如何读取FIFO?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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