首页 > 解决方案 > Communication between processes - pipe and fifo

问题描述

I need to create program with 3 processes:

  1. The first process should repeatedly read /dev/urandom and send 15 chars each cycle to the second process via a pipe.
  2. The second process should convert received data to hex and send the result to the third process via a fifo.
  3. The third process should print the received data.

This is what I wrote so far. Communication using the pipe is working fine, however there is some problem with the fifo - when I change n to a larger number such as 100000 or 1000000, the program doesn't start. When it's smaller, say 500 or 1000, the program works. What could be the reason behind that?

This is how I run it:

cat /dev/urandom | ./a.out

And here is the code:

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

#define FIFO "my_fifo"

int main(void) {
    int pdesk[2];
    char buf[15];
    char buffer[15];
    char hex[30];
    char f[30];
    int len;
    int n;

    n = 100;

    umask(0);
    mkfifo(FIFO, 0666);

    pipe(pdesk);

    if (fork() == 0) {
        for (int i = 0; i < n; i++) {
            read(STDIN_FILENO, buffer, 15);
            write(pdesk[1], buffer, 15);
        }
        close(pdesk[1]);
    } else {
        sleep(1);
        int fp;

        for(int i = 0; i < n; i++) { 
            read(pdesk[0], buf, 15);

            for(int a = 0, b = 0; b < 30; ++a, b+= 2) 
                sprintf(hex + b, "%02x", buf[a] & 0xff);

            fp = open(FIFO, O_WRONLY);
            write(fp, hex, 30);
            close(fp);
            usleep(10000);
        }
        close(pdesk[0]);
    }

    if (fork() == 0) {
        sleep(2);
        int fp;

        for (int i = 0; i < n; i++) {
            fp = open(FIFO, O_RDONLY);
            read(fp, f, 30);
            printf("Odczytano: %s\n", f);
            close(fp);
            usleep(10000);
        }
    }    
}

标签: clinuxpipefifomkfifo

解决方案


如果我理解您的代码正确,它将执行以下操作:

首先fork,您启动一​​个从标准输入读取并写入管道的子进程。

您的父进程从管道中读取数据并写入 FIFO。

当您的父进程完成其循环时,它会调用第二个fork来创建另一个子进程,该子进程将从 FIFO 读取并打印数据。

当循环计数太大时,您将达到 FIFO 的缓冲区限制,并且父级将阻塞,因为没有进程正在从 FIFO 读取。当进程在写入 FIFO 时被阻塞时,它永远不会创建预期从 FIFO 读取的子进程。

我认为主要问题是您应该在开始从管道读取数据并写入 FIFO 的循环之前创建第二个孩子。

一些补充说明:

cat /dev/urandom | ./a.out你的程序不/dev/urandom直接读取。它从可能表现不同的管道中读取。

您应该始终检查read. 它会告诉您它已读取的字节数可能少于您要求它读取的字节数。如果你想要正好有 15 个字符,如果你得到的字符少于 15 个,你可能需要多读几次。这同样适用于write


推荐阅读