gpt4 book ai didi

C - 单 shell 管道实现不断在终端中挂起

转载 作者:行者123 更新时间:2023-11-30 17:20:22 30 4
gpt4 key购买 nike

我一直在尝试在 shell 程序中实现管道结构,如果我执行简单的命令(例如“hello | rev”),它就可以工作

但是当我尝试执行“head -c 1000000/dev/urandom | wc -c”时它会挂起(忽略引号)

我的实现是:

             int fd[2];
pipe(fd);
// IN CHILD
// Piping for the first command
if (isPiped && (e == list_begin(&p->commands)))
{

close(fd[0]);
dup2(fd[1], 1);
close(fd[1]);

}

// Last command in the pipe
else if (isPiped && (list_next(e) == list_tail(&p->commands)))
{

close(fd[1]);
dup2(fd[0], 0);
close(fd[0]);

}

// IN PARENT
if (isPiped && (e == list_begin(&p->commands)))
{
close(fd[1]);
}

else if (isPiped && (list_next(e) == list_tail(&p->commands)))
{
close(fd[0]);
}

我被教导要在使用完文件描述符后始终关闭它,我认为这就是我正在做的事情 - 但我在某处发生文件描述符泄漏,我不知道在哪里。我一直在尝试对 fd 进行关闭和 dup2 的多种组合,但无济于事。

为了进一步给出一个完整的问题,这是主要的相关代码:

我这样做的方式是使用列表结构将每个命令/作业添加到列表中。变量“e”是列表的一个元素。

int main(int ac, char *argv[]) {

int numPipes = list_size(&commands) - 1;
bool isPiped = false;
if (numPipes > 0)
isPiped = true;

int fd[2];
pipe(fd);

pid_t pid = fork();
// In child
if (pid == 0)
{
if (isPiped && (e == list_begin(&p->commands)))
{
close(fd[0]);
dup2(fd[1], 1);
close(fd[1]);
}

// Last command in the pipe
else if (isPiped && (list_next(e) == list_tail(&p->commands)))
{
close(fd[1]);
dup2(fd[0], 0);
close(fd[0]);
}
// command is a struct. I have it set up so that the terminal can read in what the user inputs
execvp(command->argv[0], command->arg);

}
// In parent
if (isPiped && (e == list_begin(&p->commands)))
{
close(fd[1]);
}

else if (isPiped && (list_next(e) == list_tail(&p->commands)))
{
close(fd[0]);
}
int status;
waitpid(-1, &status, WUNTRACED);
}

这就是我的管道算法的全部内容。其余的仅用于其他内置作业,例如前台、后台、kill 命令和 io 重定向。非常感谢!

最佳答案

父进程在启动两个子进程后应关闭管道的两端。如果它不关闭管道的写入端,则从管道读取的子进程将永远不会收到 EOF,因此它永远不会终止。如果它没有关闭管道的读取端,但正在读取的子进程在读取所有输入之前终止,则正在写入的子进程将永远不会收到错误并且将阻塞,等待父进程读取无意阅读。

所以,家长只需要:

close(fd[0]);
close(fd[1]);

关于C - 单 shell 管道实现不断在终端中挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28598129/

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