我如何使用两个管道在UNIX下的C? [英] How do I use two pipes in Unix C?

查看:110
本文介绍了我如何使用两个管道在UNIX下的C?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有功课要做,上面写着以下内容:

I have a homework to do that says the following:

C编写一个程序,创建了一个孩子谁还会创建一个孩子,使三个进程之间的管道,拳头过程(父亲)将连接第二个(孩子)和儿童将与第三(子连接孩子)。我们的计划应该显示谁使用bash作为默认的shell系统的用户总数。该方案的结果应该是相同的猫的/ etc / passwd文件| grep的/斌/ bash的$| WC-L

Write a program in C that creates a child who will also create a child, make a pipe between the three processes, the fist process(father) will connect the second(child) and the child will connect with the third (child of the child). Our program should display the total number of system users who use bash as default shell. The result of the program should be identical to the "cat / etc / passwd | grep" / bin / bash $ "| wc-l"

我感到困惑与第一子和我们关闭第一管道,并打开第二次在同一时间的方法。如果你回复我用正确的code我将它已了解正确的一次。

I am confused with the first child and the method that we close the first pipe and open the second in the same time. If you reply me with the right code I 'll undestand it right once.

感谢您。

下面是我已经到目前为止写道:

Here is what I 've wrote so far:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main()
{
int pid, pid2;
int fd[2];
int fd2[2];
char *arg[3];
char *arg2[3];
char *arg3[3];  
if (pipe(fd) == -1)
{
    perror("pipe");
    exit(1);
}
pid = fork();
if (pid == -1)
{
    perror("fork");
    exit(2);
}
if (pid == 0)
{
    if (pipe(fd2) == -1)
    {
        perror("pipe");
        exit(11);
    }
    pid2=fork();
    if(pid2 == -1)
    {
        perror("fork 2");
        exit(22);
    }
    if (pid2 == 0)
    {
        //i am child 2 (child of the child)
        close (fd2[1]);
        dup2 (fd2[0],0);
        close (fd2[0]);
        arg3[0] = "wc";
        arg3[1] = "-l";
        arg3[2] = NULL;
        execvp("wc", arg3);
        perror("execvp second child");
    }
    else
    {
        //i am child 1
        close (fd[1]);
        dup2(fd[0],0);
        close (fd[0]);
        close (fd2[0]);
        dup2(fd2[1],1);
        close (fd2[1]);
        arg2[0] = "grep";
        arg2[1] = "/bin/bash$";
        arg2[2] = NULL;
        execvp("grep", arg2);
        perror("execvp first child");
    }
}
else
{
    //i 'm the father
    close (fd[0]);
    dup2(fd[1],1);
    close (fd[1]);
    arg[0] = "cat";
    arg[1] = "/etc/passwd";
    arg[2] = NULL;
    execvp("cat", arg);
    perror("execvp father");    
}   

}

推荐答案

您的程序非常接近的作品。现在缺少的是

Your program very nearly works. What's missing is

    //i am child 2 (child of the child)
    close (fd[1]);
    close (fd[0]);

您称为FD管道是'猫'和'grep的'之间的通信。发生了什么事在当前code是猫转储文件并退出,关闭其输出。 grep的读取所有这一切,并等待其输入的EOF。由于子2仍具有管开(它继承它通过fork)的输入端,grep的永远等待。如果运行程序,然后键入 PS 你应该会看到一个grep和一个厕所附近转悠等待完成。

The pipe you called fd is for communicating between 'cat' and 'grep'. What's happening in your current code is that cat dumps the file and exits, closing its output. Grep reads all of that and waits for the EOF on its input. Since "child 2" still has the input side of the pipe open (it inherited it via fork), grep waits forever. If run your program and then type ps you should see a grep and a wc hanging around waiting to finish.

建造这样一个管道时,你通常会做的另一件事是安排吧,这样最后的任务(在这种情况下WC)是壳正在等待之一。正如所写的,当你的程序是从shell中运行它的时候会出现猫完成完成和wc的输出将打印仿佛从后台任务。如果你安排的管道,使WC是我是孩子1下则shell将等待厕所吧。

The other thing you would normally do when constructing a pipeline like this is arrange it so that the final task (in this case wc) is the one that the shell is waiting for. As written, when your program is run from the shell it will appear to finish when cat finishes, and the output of wc will print as if from a background task. If you arrange the pipe so that wc is under "i am child 1" then the shell will be waiting for wc instead.

另外,您可以派生的的三个过程的所有的关闭,孩子1将调用等待()来等待所有这些之前退出。这等待的过程会像自己微小的外壳。

Alternatively you could fork all of the three processes off and "child 1" would invoke wait() to wait for all of them before exiting. That waiting process would be like your own tiny shell.

这篇关于我如何使用两个管道在UNIX下的C?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆