我有一个使用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);
}
}
答案 0 :(得分:2)
正如我在评论中指出的那样,问题出在作业pipes[pipes_count] = new_pipefd;
上:
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++;
问题是变量new_pipefd
是一个数组,所以你要将同一个数组的地址复制到pipes
的每个元素中,这意味着父变量只有访问最后创建的管道。
我认为你应该使用更像代码的代码:
int pipes_count = 0;
int pipes[MAXCLIENTS]; // Changed type!
int new_pipefd[2];
char pipe_buffer[MAXDATASIZE];
while (1)
{
// Pipe creation
pipe(new_pipefd);
pipes[pipes_count++] = new_pipefd[0]; // Just the read end of the pipe
if (fork())
{
// unrelated code for parent here
close(new_pipefd[1]); // close the parent's write-end of the pipe
// break; // This break is not wanted
}
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++) {
int pipe_bytes = read(pipes[i], pipe_buffer, sizeof(pipe_buffer));
if (pipe_bytes != 0)
printf("Testing: %.*s\n", pipe_bytes, pipe_buffer); // Safe!
close(pipes[i]);
}
如果是我的代码,我有一个函数(我传统上称之为be_childish()
)来调用&#39;如果它是一个孩子&#39;循环中的代码块。该函数永远不会返回,并且会传递它所需的任何资源(new_pipefd
肯定,也可能是其他信息)。我经常有一个函数be_parental()
来做父母的活动。我发现这可以清除大部分代码,迫使活动清晰分离。