linux中的管道实现和管道

inux的shell中有个很常用的东西管道,很多人认为他是shell的精华了 (我没什么感觉,可能是用的比较少的原因),意思就是把一个命令的输出,作为另一个进程的输入。而在上操作系统课程时候,老师曾经给我们讲过进程通信中的 管道这一个概念。在linux具体的实现就是pipe函数,可以说这个和shell中的管道,我认为就是一个东西,shell中的管道就是用pipe函数 来实现的(有点武断,因为我没看过 shell的源代码)。为了说明这一点,我们写一个程序来模拟管道。

 

具体例子:我们输入 ls -l | wc这是一个管道的简单例子,大家可以自己试试,可以通过man帮助来查查这个指令的意思,应该不难。

 

前提知识介绍:

1.文件的数据结构描述:管道通信,就是在2个进程间建立一个管道(其实具体是的实现,是一个虚拟的文件,这个文件只存在于内存中,所以是个虚拟 的)一个进程掌握写入段,另一个掌握读出段。linux把设备看作文件,以前我们就说过标准输入是0,输出是1,错误输出是2。具体的意思是:每个进程都 有一个files数组,files[0]就是键盘了(一般是,我们程序就不是了,我们改掉了), files[1]就是显示器, files[2]是错误输出(应该是null)。

 

我们的思路是:由父进程创建2个子进程b 和c,父进程传建一个管道,管道是个虚拟文件,我们把这个文件输出段,其实也是一个file结构替换掉子进程的标准输入文件,输入段替换掉子进程的标准输入文件,这样我们就是先了shell中的管道。

 

具体代码:

[root@liumengli pipe]# cat pipe_father_3.c
#include "stdio.h"
#include "unistd.h"

int main() {
        pid_t child_b, child_c;
        int pipefds[2]; //[0] for read, [1] for write
        char * arg1[] = {"/usr/bin/wc", NULL};
        char * arg2[] = {"/bin/ls", "-l", NULL};

        //父进程
        pipe(pipefds); // 开始创建管道的2段

        if(!(child_b = fork())) { //创建子进程b
                close(pipefds[1]); /* 关掉管道的读取端*/
                close(0); //关掉b进程的标准输入文件,其实就是键盘
                dup2(pipefds[0], 0); //将我们管道的输出段复制到 b进程的标准输入中
                close(pipefds[0]); //关掉输出
                execve("/usr/bin/wc", arg1, NULL); //执行wc进程
                printf("pid is %d, wc/n", getpid()); //只有出错才会到这里
        }
        close(pipefds[0]); /*close read*/

        if(!(child_c = fork())) { //创建子进程c
                close(1); //和上面雷同
                dup2(pipefds[1], 1);
                close(pipefds[1]);
                execve("/bin/ls", arg2, NULL);
                printf("pid is %d, ls/n", getpid());
        }

        close(pipefds[1]);
        wait4(child_b, NULL, 0, NULL);
        return 0;
}

[root@liumengli pipe]# ls -l | wc
     15     128     763
[root@liumengli pipe]# ./pipe_father_3
     14      128    763

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值