多个进程之间的FIFO - 仅从单个进程打印

时间:2015-11-12 00:15:59

标签: c multithreading multiprocessing

我正在尝试在两个程序之间创建一个FIFO(一个是另一个程序的子进程),以便子进程可以将数据写回父进程。这是我到目前为止所做的:

(家长)

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

#define MAX_BUF 1024

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

    //number of seperate processes to create
    int num_processes = 4;
    int i = 0;

    //FIFO accross processes
        int fd;
        char * myfifo = "/tmp/myfifo";
        char buf[MAX_BUF];
        /* create the FIFO (named pipe) */
        mkfifo(myfifo, 0666);

    for (i; i < num_processes; i++) {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork failed");
        exit(1);
    }
    else if (pid == 0) {
        //child now exec's
        char* args[] = {"./child", "args", NULL};
        execv("./child", args); 
    }
     }

    printf("Parent doing stuff\n");


    //Parent wait for child
    printf("Parent waiting on child\n");



        /* open, read, and display the message from the FIFO */
        fd = open(myfifo, O_RDONLY);
        if (fcntl(fd, F_GETFD) == -1) {
             perror("fd failed");
             exit(1);
        }   
        read(fd, buf, MAX_BUF);
        printf("Received: %s\n", buf);

    //Wait for child processes to finish
    int j = 0;
        for (j; j < num_processes; j++) {
    wait(NULL);
    }
    //Close FIFO
        close(fd);
    return 0;
}

(孩子,创造了4次)

void main() {

    printf("Completed\n");

   //Create FIFO
    int fd;
    char * myfifo = "/tmp/myfifo";



    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    if (fcntl(fd, F_GETFD) == -1) {
    perror("open failed");
    exit(1);
    }   
    write(fd, "Hi", sizeof("Hi"));
    //close(fd);

    /* remove the FIFO */
    //unlink(myfifo);   
}

现在,“已完成”正在打印4次,表明有4个单独的进程正在运行。但是,终端中只打印了一个“已收到:您好”。为什么我没有从其他进程获得FIFO响应?

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

您需要检查fd并确保open成功。请注意,它只能成功一次,因为第一个孩子将unlink(myfifo)

父母还应等待所有孩子完成,然后再从fifo中读完。并且父级应该在循环中读取fifo,直到fifo为空。

答案 1 :(得分:0)

代码中的问题是有多个子写入同一个FIFO。

正如user3386109所指出的那样,你必须等待每个孩子并读取FIFO。 这是一个示例代码:

   //Wait for child processes to finish
        int child_status = 0;
        while (wait(&child_status) !=  -1) {
                if (WIFEXITED (child_status)) {
                        fprintf (stdout, "the child process exited normally, with exit code %d\n", WEXITSTATUS (child_status));

                        // Read The buffer
                        read(fd, buf, MAX_BUF);
                        printf("Received: %s\n", buf);

                }
                else fprintf (stderr, "the child process exited abnormally\n");
        }

我还建议向孩子传递一个id(如果需要,这只是一个示例添加检查):

   else if (pid == 0) {
        //child now exec's
        char mypid[10];
        snprintf(mypid, 10, "%d", i);
        char* args[] = {"./child", mypid, NULL};
        execv("./child", args);
        sleep(1);

每个孩子都阅读了argv [1]

int mypid = atoi(argv[1]);

请参阅此帖:C Named pipe (fifo). Parent process gets stuck

答案 2 :(得分:0)

通过将我的read语句放入循环中来等待子进程完成来解决:

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);

    if (fcntl(fd, F_GETFD) == -1) {
    perror("fd failed");
    exit(1);
}               


//Wait for child processes to finish
int j = 0;
    for (j; j < num_processes; j++) {
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    wait(NULL);
}
//Close
    close(fd);
return 0;