在子进程完成FIFO的写入之后,父进程如何读取FIFO?

时间:2019-03-28 10:35:07

标签: c linux named-pipes fifo systems-programming

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

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

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

我的程序是这样的:

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

1 个答案:

答案 0 :(得分:3)

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

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

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