我正在使用这两个程序的this答案。这个答案使用命名管道而不是管道,我是否正确?在管道中传输的数据是垃圾
我写了main.c,它实际上是我的实际项目的代码,最小化到这个特定的问题(这就是为什么我有一个for循环为例)。
#include <unistd.h>
#include <sys/wait.h>
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
int main(void) {
pid_t pid;
int i;
for(i = 0; i < 2; ++i) {
pid = fork();
if (pid == -1) {
// error, failed to fork()
perror("failed to fork()");
return 1;
} else if (pid == 0) {
// child code
if(i < 1) {
// the writer.c
char* arg_list[] = { "w", NULL };
execv("w", arg_list);
printf("exec FAILED\n");
} else {
// the reader.c
char* arg_list[] = { "r", NULL };
execv("r", arg_list);
printf("exec FAILED\n");
}
}
}
// parent code
int status;
// wait for all children to terminate
while ((pid = wait(&status)) > 0) {
if (status == 1) {
printf("The child process terminated with an error!\n");
return -1;
}
}
printf("All children are done\n");
return 0;
}
的问题是,有时,读取器接收垃圾(或最有可能没有),并挂断了电话。
输出示例:
Received: Hi
All children are done
[email protected]:~/test$ ./m
Received: Hi
All children are done
[email protected]:~/test$ ./m
Received: <----------------- This is garbage, that is not reproducible
^C
所以,我缺少什么?
不需要在下面阅读。
我的猜测。(不检查,所以如果我是正确的,我仍然需要澄清):
读写器之前运行,这就是为什么它有垃圾,但为什么它挂起?
或
我需要写一个包装函数read_all()
(一个用于写入的情况下呢?),收集所有的管道吐数据,但为什么,如果我取代“喜”与“H “,我有同样的行为?
编辑:
如果我的第一个猜测的话,我把一个循环的阅读,但它会在读者先启动的情况下永远执行。
在我看到垃圾的情况下,与strace -f
运行后,我得到这个:
...
[pid 3326] read(-1, 0xbfddd80c, 1024) = -1 EBADF (Bad file descriptor)^C
Process 3324 resumed
Process 3325 detached
Process 3326 detached
*您应该*在read()方法周围使用读循环来确保读取所有字节。同样,你应该在write()方法周围使用写循环来确保写入所有字节。但是,我认为你没有做这些事情对你所观察到的行为负责。在'strace -f'下运行你的程序可能会提供更多的洞察。 – 2014-11-14 21:05:54
请注意,如果您不需要或不想管理低级'read()'和'write()'调用,您可以'打开()'您的FIFO并使用流I/O。 – 2014-11-14 21:08:10
那么在这种情况下,我应该怎么知道我需要阅读多少个角色?我并不清楚这一开始。我的意思是我真的不知道这个循环如何看起来像@JohnBollinger。 – gsamaras 2014-11-14 21:08:41