【问题标题】:implementing pipeline using fork and pipe使用 fork 和 pipe 实现管道
【发布时间】:2014-05-31 10:17:42
【问题描述】:

我需要使用 fork 为我的操作系统类实现无名管道,但我无法让它工作。它是一个简单的代码,并没有什么特别之处,但我什么也没得到。我试图跑 ls -l | wc -l 但我每次都得到 0。

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h> // for open flags
#include <time.h> // for time measurement
#include <assert.h>
#include <errno.h>
#include <string.h>

int pid,status;
int pipefd[2];

void my_exec(char* cmd, char** argv)
{
    pipe(pipefd);     // Fixed
    pid = fork();
    // pipe(pipefd);  // Original

    if(pid==0){
        close(pipefd[0]);
        dup2(pipefd[1],fileno(stdout));
        close(pipefd[1]);
        execvp(cmd, argv);


    }
    else {
        close(pipefd[1]);
        dup2(pipefd[0],fileno(stdin));
        while(wait(&status)!=-1);
        close(pipefd[0]);
        return; 
    }

}

int main(int argc, char** argv)
{
    assert(strcmp(argv[argc-1], "-"));

    int i;
    for (i = 1; i < argc; ++i) {
        if (!strcmp(argv[i], "-")) {
            argv[i] = NULL;
            my_exec(argv[1], &argv[1]);
            argv = &argv[i];
            argc -= i;
            i = 0;
        }

    }

    char* args[argc];
    args[argc-1] = NULL;
    for (i = 1; i < argc; ++i) {
        args[i-1] = argv[i];

    }

    if (execvp(args[0], args) == -1)
        perror("execvp failed");
    return;
}

顺便说一句,我尝试的命令的输入是 ls -l - wc -l(而不是 | type -)

OK Duck 解决了它:我应该在 fork 之前创建管道,更新。

【问题讨论】:

  • 你不是在“实现管道”。您正在使用管道和分叉来创建管道。也许这是语义上的狡辩,但“使用 fork 实现管道”是一个非常奇怪的表达方式。
  • 对于初学者来说,在fork之前创建管道。
  • 旁注:如果孩子被阻塞,等待孩子终止将不起作用,因为它向管道写入太多。
  • @Duck 你是对的,我修好了谢谢

标签: c linux fork pipe


【解决方案1】:

您最大的问题是叉子在管道前面。这将有效地使 fork 的每个分支调用pipe(),因此您最终会得到两个不同的 pipefd 集,而不是同一个集。颠倒fork()和pipe()的调用顺序,那么每个fork中的文件描述符都是一样的。

作为旁注,您可以在每个 if() 语句组件中执行 printf() 进行调试,以确保您看到的描述符总数永远不会超过两个。

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 2020-05-07
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多