首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C语言实现管道

问用C语言实现管道
EN

Stack Overflow用户
提问于 2015-05-12 12:24:35
回答 1查看 3K关注 0票数 3

我刚刚完成了shell解释器,但我认为我的管道实现是错误的。

它正在工作,像ls | cat -e这样的基本东西可以工作,但是如果文件描述符超过60 ko,我担心segmentation fault可能会出现。我还发现了一个无限循环,当我做一个文件的猫,它的长度超过60 ko。例如,如果do是cat foo | cat -e,而foo是一个长文件,则会发生无限循环。

或者其他例子--当我执行cat /dev/urandom | cat -e时,它没有显示任何显示,所以它首先执行cat /dev/urandom,然后执行cat -e。

这是我的密码:

代码语言:javascript
复制
int son(int *fd_in, int p[2], t_list *cmd, char **env)
{
    (void)env;
    dup2(*fd_in, 0);
    if (cmd->act != ENDACT && cmd->act != LEFT && cmd->act != DLEFT)
        dup2(p[1], 1);
    close(p[0]);
    execve(cmd->av[0], cmd->av, NULL);
    return (-1);
}

t_list *execute_pipe(t_list *cmd, int *fd_in)
{
    int           p[2];
    pid_t         pid;

    *fd_in = 0;
    while (cmd->act != -1)
    {
        pipe(p);
        if ((pid = fork()) == -1)
            return (NULL);
        else if (pid == 0)
            son(fd_in, p, cmd, NULL);
        else
        {
            wait(NULL);
            close(p[1]);
            *fd_in = p[0];
            if (cmd->act != PIPE)
                return (cmd);
            cmd = cmd->next;
        }
    }
    return (cmd);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-12 13:59:40

shell管道的部分思想是所涉及的进程同时运行(或可能运行)。在启动下一个子进程之前,您提供的代码可以通过wait()对每个子进程积极地防止这种情况发生。除其他外,这可能会在任何事情准备就绪之前填充(OS-级)管道的缓冲区。这将导致死锁,或者,如果幸运的话,会生成一个错误。

在较高级别上,程序应如下所示:

  1. shell首先让C作为管道第一个段的命令,并将fd0设置为STDIN_FILENO
  2. shell准备输出文件描述符:
    1. 如果有后续命令,创建一个pipe(),并将fd1设置为该管道的写入端;
    2. 否则,将fd1设置为STDOUT_FILENO

​

  1. shell fork()运行命令C的子程序。在其中:
    1. 子如果fd0与STDIN_FILENO不同,则dup2() fd0到STDIN_FILENO并关闭fd0
    2. 子如果fd1与STDOUT_FILENO不同,则dup2() fd1到STDOUT_FILENO并关闭fd1
    3. 子 exec命令C

​

  1. 如果shell与STDIN_FILENO不同,则关闭fd0
  2. 如果shell与STDOUT_FILENO不同,则关闭fd1
  3. 如果管道中还有其他命令,则为,则为
    1. 将C设置为下一个命令
    2. 将fd0设置为上述步骤(2)中管道的读取端
    3. 转到步骤2(准备输出文件描述符)

​

  1. shell (此时,管道中的所有进程都已启动。)用于所有子进程的wait()或waitpid()

请注意,对于包含任意数量的命令(包括1 )的管道来说,这同样有效。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30190809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档