c - Communication between processes - pipe and fifo
问题描述
I need to create program with 3 processes:
- The first process should repeatedly read
/dev/urandom
and send 15 chars each cycle to the second process via a pipe. - The second process should convert received data to hex and send the result to the third process via a fifo.
- 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);
}
}
}
解决方案
如果我理解您的代码正确,它将执行以下操作:
首先fork
,您启动一个从标准输入读取并写入管道的子进程。
您的父进程从管道中读取数据并写入 FIFO。
当您的父进程完成其循环时,它会调用第二个fork
来创建另一个子进程,该子进程将从 FIFO 读取并打印数据。
当循环计数太大时,您将达到 FIFO 的缓冲区限制,并且父级将阻塞,因为没有进程正在从 FIFO 读取。当进程在写入 FIFO 时被阻塞时,它永远不会创建预期从 FIFO 读取的子进程。
我认为主要问题是您应该在开始从管道读取数据并写入 FIFO 的循环之前创建第二个孩子。
一些补充说明:
用cat /dev/urandom | ./a.out
你的程序不/dev/urandom
直接读取。它从可能表现不同的管道中读取。
您应该始终检查read
. 它会告诉您它已读取的字节数可能少于您要求它读取的字节数。如果你想要正好有 15 个字符,如果你得到的字符少于 15 个,你可能需要多读几次。这同样适用于write
。
推荐阅读
- dynamic - 具有动态行高的 SSRS Tablix 控件
- regex - 在 mod_rewrite 中使用有效的正则表达式减少路径
- jquery - VBA 将数据输入到 Jquery 表中以在网站上提交搜索
- f# - 如何使用单个根对简单层次结构建模
- testing - .NET Standard 库的单元测试项目是否应该针对 .NET Core 以外的框架?
- vba - 使用 VBA 设置从 word 到 excel 的文档合并的问题
- sql - SQL:将数字日期更改为“日期”
- visual-studio - 理论的内联数据不跟踪 R# runner 中的变化
- ruby-on-rails - Rails 部署,捆绑 exec rails s vs Nginx 和 Passenger
- angular - 以 2/5 角聚焦输入