我需要用3个过程创建程序:
第一个进程应重复读取/dev/urandom
,并通过管道将每个周期15个字符发送到第二个进程。
第二个进程应将接收到的数据转换为十六进制,并通过fifo将结果发送到第三个进程。
第三个过程应该打印接收到的数据。
这就是我到目前为止写的。使用管道进行通信工作正常,但是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
程序不会直接读取/dev/urandom
。它从一个可能有不同行为的管道读取数据。
您应该始终检查read
的返回值。它会告诉你它读了多少字节,可能比你要求的要少。如果你想要15个字符,如果少于15个字符,你可能要读几遍。
这同样适用于write
。
关于c - 流程之间的通信-管道和FIFO,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53870872/