gpt4 book ai didi

c - 如何动态创建 Unix 管道?

转载 作者:太空宇宙 更新时间:2023-11-04 08:42:22 26 4
gpt4 key购买 nike

我有一个程序使用 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);
}
}

最佳答案

正如我在评论中指出的那样,问题出在分配 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())以在循环中的“如果它是一个子项”代码块中调用。该函数永远不会返回,并且会传递它需要的任何资源(当然是 new_pipefd,也许还有其他信息)。我经常有一个函数 be_parental() 来做 parent 的事件。我发现这清理了大部分代码,迫使事件完全分离。

关于c - 如何动态创建 Unix 管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23097893/

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