【发布时间】:2014-04-16 02:23:16
【问题描述】:
我有一个程序使用fork() 创建子进程,我想让子进程使用 Unix 管道与父进程通信。
问题是似乎没有创建多个管道,或者我的数组可能有问题。当我在父程序中使用prinf() 时,它从每个管道读取相同的数据,即使每个子程序发送不同的数据。
这是我的代码:
// Variables
int pipes_count = 0;
int *pipes[MAXCLIENTS];
int new_pipefd[2];
int pipe_bytes;
char pipe_buffer[MAXDATASIZE];
while(1) {
// Pipe creation
pipe(new_pipefd);
pipes[pipes_count] = new_pipefd;
pipes_count++;
if (fork()) {
// unrelated code for parent here
close(new_pipefd[1]); // close the parent's write-end of the pipe
break;
} else {
// unrelated code for child here
close(new_pipefd[0]); // close the child's read-end of the pipe
break;
}
if (some condition) { break; } // The parent will stop creating pipes
}
while(condition that guarantees this is the child) {
write(new_pipefd[1], buffer, strlen(recv_buffer));
close(new_pipefd[1]);
return 0; // the child process ends
}
// This is a loop where the parent reads what the children sent
for (int i = 0; i < pipes_count; i++) {
pipe_bytes = read(pipes[i][0], pipe_buffer, sizeof pipe_buffer);
if (pipe_bytes == 0) {
close(pipes[i][0]);
} else {
printf("Testing: %s\n", pipe_buffer);
}
}
【问题讨论】:
-
你不能像C中的
pipes[pipes_count] = new_pipefd;那样做数组赋值。你需要检查fork()的返回值来知道代码是父代码还是子代码。通过显示的代码,我们无法判断您到底在做什么;提到了一个循环,但你要做什么真的很重要。子进程在完成子进程的代码后,显然最终会执行父进程的代码。请发布更多您的真实代码 - 有很多事情可能会出错,很难猜测您遇到了什么问题。 -
那我怎样才能得到一个管道数组(文件描述符)呢?为了简单起见,我从这篇文章中删除了检查
fork()的返回值的代码,我应该让 cmets 更清晰。在我的实际源代码中,让代码在父级与子级中运行正常。编辑:刚刚看到你的编辑。我会回去尝试让一切更清楚。 -
我收回;你的
pipes是int *的数组,而不是int;我的错。但是,您的代码似乎将指针new_pipefd复制到数组中的每个位置,这不会有太大帮助。您需要能够存储不同的值。由于您没有显示所有代码,我们无法判断您是否正确但没有显示它。然而,从表面上看,一切都是从最后一个孩子那里读来的。您需要父进程关闭管道的写入端。事实上,一般来说,使用管道,很多问题都是由于没有关闭足够多的文件描述符造成的。