gpt4 book ai didi

进程间通信——pipe和fifo

转载 作者:太空宇宙 更新时间:2023-11-04 10:04:03 25 4
gpt4 key购买 nike

我需要创建包含 3 个进程的程序:

  1. 第一个进程应重复读取 /dev/urandom 并通过 pipe 每个周期向第二个进程发送 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 的循环之前创建第二个 child 。

补充说明:

使用 cat/dev/urandom | ./a.out 你的程序不直接读取/dev/urandom。它从一个行为可能不同的管道中读取。

您应该始终检查read 的返回值。它会告诉你它已经读取了多少字节,这可能比你要求它读取的要少。如果你想要刚好有 15 个字符,如果少于 15 个字符,你可能需要多读几遍。这同样适用于write

关于进程间通信——pipe和fifo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53870872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com