繁体   English   中英

流程之间的通信-管道和FIFO

[英]Communication between processes - pipe and fifo

我需要用3个进程创建程序:

  1. 第一个进程应该重复读取/dev/urandom并且每个周期通过管道将15个字符发送到第二个进程。
  2. 第二个过程应该将接收到的数据转换为十六进制,然后通过fifo将结果发送到第三个过程。
  3. 第三步应该打印接收到的数据。

这是我到目前为止写的。 使用管道的通信工作正常,但是fifo存在一些问题-当我将n更改为较大的数字(例如100000或1000000)时,程序无法启动。 当它较小时(例如500或1000),该程序将起作用。 这可能是什么原因?

这是我的运行方式:

 cat /dev/urandom | ./a.out 

这是代码:

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

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

使用第一个fork您将启动一个从stdin读取并写入管道的孩子。

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

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

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

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

一些补充说明:

cat /dev/urandom | ./a.out cat /dev/urandom | ./a.out您的程序不会直接读取/dev/urandom 它从行为可能不同的管道读取数据。

您应该始终检查read的返回值。 它会告诉您已读取的字节数可能少于您要求的字节数。 如果要精确地包含15个字符,则少于15个字符可能需要阅读几次。 同样适用于write

非常感谢你。 当显示数据的进程位于其他子进程之上时,它最终将工作。

与cat / dev / urandom | ./a.out您的程序不会直接读取/ dev / urandom。 它从行为可能不同的管道读取数据。

我该如何更改?

程序还需要以与从/ dev / urandom读取相同的方式读取文件,例如:

cat file.txt | ./a.out

我听取了您的建议,开始检查read的值,现在它没有超出文件范围。 问题是我不知道如何检查调用了哪个参数(因此我无法检查文件的长度)-如果是file.txt,/ dev / urandom,没有其他任何东西。 我尝试过

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

但是argv始终是./a.out,无论我叫什么。 有什么办法可以检查吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM