gpt4 book ai didi

c - 为什么我无法写入或读取管道?

转载 作者:行者123 更新时间:2023-11-30 15:11:54 25 4
gpt4 key购买 nike

我见过很多类似的问题,但它们都针对具体情况,并没有帮助我找到解决方案。如果您对我的情况有任何反馈,我将不胜感激,如下:

我正在尝试编写一个程序来从文本文件中获取字符计数。该程序的工作原理是 fork 4 个映射器和 26 个缩减器,并为每个映射器创建管道。父进程将输入分成四行,并将一行传递给每个映射器,该映射器计算该行中每个字符的数量。然后,每个映射器将计数传递给适当的化简器,该化简器将所有四个计数相加并打印结果。

下面是迄今为止我的代码:

 int main(int argc, char *argv[])
{
int i = 0;

FILE *input = fopen("input.txt", "r");

// Things for reading line-by-line: see getline reference on man7.org
char *line = NULL;
size_t len = 0;

// Where we'll store the messages
static char message[MSGSIZE];

for(i = 0; i < NUMREDUCERS; i++)
{
pipe(reducer_pipes[i]);
}

for(i = 0; i < NUMMAPS; i++)
{
// Step 1: Create pipes for communication using the system call pipe()
pipe(mapper_pipes[i]);

// Step 2: Fork a number of mappers (4).
if (fork() == 0)
{
// Don't want to close the write pipe yet
// Child process: one of the mappers

read(mapper_pipes[i][0], message, MSGSIZE); // Read from reading end
char *msg = "Error reading from pipe";
check_errors(msg);

// Get char count and write to pipe
int j = 0;
int ccount = 0;
for(j = 0; j < NUMREDUCERS; j++)
{
// Count up the number of chars
ccount = count_char(message, (char) (j + 97), MSGSIZE);

// Write to the appropriate reducer pipe
write(reducer_pipes[j][1], (char *) ccount, MSGSIZE);
msg = "error writing to reducer pipe";
check_errors(msg);

}

exit(EXIT_SUCCESS);
}
else
{
getline(&line, &len, input);
// Parent process

write(mapper_pipes[i][1], line, (int) len);
char *msg = "Error writing to pipe";
check_errors(msg);
}
}

return 0;
}

我遇到的问题是我无法写入 reducer 管道。每当我尝试写入、读取或关闭它们时,我都会收到错误地址错误。它们是否以某种方式过期了?我没有正确创建它们吗?如果有人可以提供意见,我将不胜感激。

快速编辑:我已删除所有“关闭”语句,因为它们有相同的问题。但是,我尝试关闭应该关闭的管道,却发现相同的错误消息。

最佳答案

“错误地址”(errno == EFAULT) 表示您向系统调用传递了无效的指针。它本质上相当于一个段错误(我相信有些系统实际上只是在这种情况下引发SIGSEGV)。

看这一行:

      write(reducer_pipes[j][1], (char *) ccount, MSGSIZE);

这里ccount是int类型。将 int 转换为指针总是可疑的。

在上一行中,您将 ccount 分配给 count_char() 的返回值。现在您没有向我们展示该函数的代码,但我猜测它会返回字符计数 - 很可能是一个小整数。假设它返回 17。您告诉 write 写入位于地址 17 处的 MSGSIZE 字节。这肯定不是您想要的。

如果您想以二进制格式将该整数发送到 reducer ,您可能想说

write(reducer_pipes[j][1], &ccount, sizeof(ccount));

当然,您必须在reducer端有匹配的代码。

<小时/>

其他人已经解决了代码中的许多其他问题,例如仅通过查看 errno 无法可靠地检测错误(这大概就是 check_errors 确实)。如果系统调用没有错误,则 errno 保持不变,即使它之前有一个非零值。您应该做的是检查 write() 的返回值;如果是 -1 则发生错误,只有在那时您才应该查看 errno (或调用 perror)来了解它是什么。

基本上,每当您进行系统调用并且不检查返回值时,就会遇到错误。

关于c - 为什么我无法写入或读取管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35371227/

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