UNIX管道应用及Shell实现(三)-多管道实现


本篇主要介绍多管道实现,自己也写得不好,希望大家多多指点。

思路

我在这篇文章中较详细的讲解了管道的实现,但当时只涉及到一个管道,因此只需要关心对管道的read和write,并不需要关心read到什么地方去。
首先,我们在使用pipe创建管道后,需要fork一个进程,子进程用于向管道写,父进程用于向管道读(注意,顺序不能颠倒)。很有趣的一个问题是,当我们使用fork命令时,子父进程的执行顺序是不能确定的,那么是让父进程向管道读还是子进程向管道读呢?
我的理解是,由于父进程不能先于子进程结束,而如果管道中没有东西,从管道读的操作会被堵塞,可以利用这个性质让子进程先于父进程结束。具体做法就是:让父进程向管道读,子进程向管道写。由于“向管道写”操作总是先于“向管道读”操作,因此可以做到父进程结束前回收子进程的工作。
那么,我们怎么做到多管道进行操作呢?其实也不难,我们可以先把所需要的所有管道建立好,然后当子进程要进行execv操作之前,把它的输出fd指向下一个管道的输入,这样重复进行就能实现多个管道进行通讯了。
要注意的是,当进行到最后一个命令,这时候我们需要判断:若最后一个命令就是“|”,则我们需要将管道中的数据输出到屏幕即可;若最后一个命令时”>”,则需要将管道中的命令写入对应的文件中。

实现

总体来说对于管道的操作有三种情况:
1. 最开始有“<”重定向符号,接着有多个管道。
2. 一开始就是多个管道进行传输,最后输出到屏幕。
3. 通过多个管道传输后,最后重定向到指定文件。

其实这三种情况都可以写成一个函数,因为只需要对第一个命令和最后一个命令进行特殊处理即可。由于笔者很蠢,最开始没想到第一种情况,因此后面只能用修改字符串的方法曲线救国了,代码很丑,将就看吧。
pipe_command:

/*take care of pipe*/
void pipe_command() {
    /*pointerindex is the index of each Command*/
    int i = 1, j = 0, pointerindex[20], commandnumber = CommandInfo.index;
    int pipenumber = 0, pid, pipefd[20][2];
    char** P_temp;
    pointerindex[0] = 0; /*the first command location*/

    /*get all command's index*/
    while (i <= commandnumber) {
        if (CommandInfo.argv[j] == NULL) {
            pointerindex[i] = j + 1;
            i++;
        }
        j++;
    }

    /*if 
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值