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

问题描述 投票:0回答:1

我有一个非常简单的基本程序,有两个过程,第一个是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);
}
c linux named-pipes fifo systems-programming
1个回答
3
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.