`
airu
  • 浏览: 270761 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论

管道管道管道

 
阅读更多
Unix的管道真的是很方便,我们经常这样用:

$ls -l|wc -l


用于统计一个目录下的文件数。这里如果详细说起来,涉及了进程组,会话的概念。当然最显眼的就是符号 | ,这是就是管道,下面我们说说上面的这句shell如何用c语言来写。为了更能说明问题,我们把结果写入一个文件中。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>

void error_quit(char *msg)
{
    fprintf(stderr,"%s\n",msg);
    exit(1);
}

int main(int argc, char *argv[])
{
        int fd[2]; //存放管道读写的描述符
        int new_fd; 

        if(pipe(fd)==-1)  //使用pipe创建管道,错误返回-1
	error_quit("pipe error");
//fork,dup和dup2都在 unistd.h 中申明
        switch(fork()){  // 偶然看到的写法,觉得新鲜。fork返回pid_t类型
        case -1: error_quit("fork error");
        case 0:  //子进程返回0
                /*
                close(1); //关闭标准输出,为了下一句能把子进程的管道写描述符复制到标准输出
                   
                dup(fd[1]); //把子进程管道写描述符复制到一个新的描述符中,由于上面关闭了标准输出,系统会选取最小的描述符作为新描述符                */
                dup2(fd[1],1);//这是另外一种写法。上面注释部分由于不是原子操作,所以可以用dup2函数,实现上面注释块的功能。
                close(fd[0]); //关闭掉不用的描述符
                close(fd[1]);
                execlp("ls","ls -l",0); //在子进程空间执行ls命令
                error_quit("try to exec ls");
                break;
        default:
                close(0);
                dup(fd[0]); //可以用dup2代替
                close(fd[0]);
                close(fd[1]);

                if((new_fd = open("result.txt",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0)
//打开一个文件,使用系统调用open,在fcntl.h中申明
                error_quit("open result.txt error");
                close(1); //关闭标准输出
                dup(new_fd); //标准输出变成文件result.txt
                execlp("wc","wc","-l",0);
                error_quit("try to wc");
                break;
	}
	exit(0);

}


现在保存,编译文件 pipe_test.c
$gcc -c pipe_test.c
...
$gcc -g -o pt pipe_test.o
...
$./pt
$cat result.txt
$28

你也可以试试是不是和 ls -l|wc -l 一样呢?
注意,父子进程之间的通讯。如果我们的子进程没有准备好数据怎么办?
对于管道,如果写进程停止,那么读进程读到0,表示结束。
如果读进程先停止,那么写进程将会收到一个SIGPIPE的信号,并且wirte返回-1,把errno设置为 EPIPE。

这就是无名管道。当然还有更复杂的FIFO,有名管道。
这里主要是要注意 dup的使用,学习如何重定向。对了,这里还忘记说了,文件描述符,也就是上面的0,1,2,3这些,是进程表中的一个索引,他指向文件表,文件表说明了这个文件的各种属性。
分享到:
评论

相关推荐

    压力管道规范-工业管道

    《压力管道规范-工业管道》是中国国家标准GB/T 20801-2006,它是指导工业生产中压力管道设计、施工、检验和安全防护的重要依据。本规范涵盖了压力管道材料选择、设计计算、制造安装、检测试验以及安全防护等多个关键...

    匿名管道与命名管道的使用

    ### 知识点一:匿名管道的理解与使用 #### 定义: 匿名管道是一种用于具有亲缘关系进程之间(如父进程与子进程)进行单向通信的方式。它不具备全局名称,仅存在于创建它的进程及其后代之间。 #### 特点: - **单向...

    命名管道实例 命名管道

    命名管道是Windows操作系统中的一种进程间通信(IPC)机制,它允许不同的进程之间进行数据交换。在本实例中,我们将深入探讨命名管道的工作原理、如何创建和使用命名管道,以及在实际开发中的应用。 首先,我们需要...

    Linux系统管道和有名管道的通信机制

    Linux系统中的管道(pipe)和有名管道(named pipe或FIFO)是进程间通信(IPC,Inter-Process Communication)的重要机制。管道最早出现在Unix系统中,是Linux支持的基础IPC形式之一,尤其适用于父子进程或兄弟进程...

    压力管道定期检验规则——公用管道.pdf

    《压力管道定期检验规则——公用管道》是针对城镇燃气输配系统中压力管道定期检验的规定,旨在确保管道的安全运行和防止潜在事故的发生。该规则涵盖了管道的检验周期、检验方法、安全保护装置的要求以及对检验发现...

    命名管道,命名管道,命名管道

    命名管道是Windows操作系统中的一种进程间通信(IPC,Inter-Process Communication)机制,它允许不同进程之间进行数据交换。在Windows系统中,命名管道提供了一种半双工(half-duplex)通信方式,即数据只能在一个...

    MFG_管道_MFC管道_

    MFC管道是MFC框架中实现进程间通信(IPC,Inter-Process Communication)的一种机制,尤其适用于在不同程序之间传递数据和参数。下面将详细解释MFC管道的概念、工作原理以及如何在实际编程中应用。 MFC管道是基于...

    压力管道设计(工业管道、公用管道).doc

    压力管道设计是工业生产和公共设施中的重要组成部分,它涉及到安全、效率和长期稳定运行。压力管道通常被分类为不同等级,以适应不同的工况和安全要求。在TSG R1001-2008《压力容器压力管道设计许可规则》中,工业...

    管道阻力计算软件管道阻力计算软件

    管道阻力计算是流体动力学中的一个重要概念,特别是在水力工程、化工、空调制冷和石油天然气等领域的管道系统设计中。阻力是指流体在管道中流动时,由于摩擦和局部障碍物引起的能量损失。理解并精确计算管道阻力对于...

    ProE管道建模的三种方法:扫描、高级管道、管道模块

    ### ProE管道建模的三种方法详解 #### 第一种方法:扫描特征 扫描特征是ProE中最基础也是最直观的管道建模方式之一。这种方法通过创建一条或一系列曲线,然后以这些曲线作为中心线,使用“扫描”命令来构建管道...

    qt有名管道demo

    **Qt有名管道(Named Pipe)Demo** 在编程领域,进程间通信(Inter-Process Communication, IPC)是一项重要的技术,它允许不同的进程之间交换数据。在跨平台开发中,选择一个能够在不同操作系统上运行的IPC机制至...

    石油化工装置工艺管道安装设计施工图册(第3分册 管道支吊架

    管道支吊架是石油化工装置中重要的组成部分,主要起到支撑管道、减轻管道自重、控制热胀冷缩带来的管道位移、固定管道位置和减少管道振动等作用。在工业管道设计中,合理设计和安装管道支吊架对于确保管道系统安全、...

    管道刚度计算软件

    管道刚度计算软件是一款专为工程领域设计的工具,主要用于评估和分析管道在受力条件下的刚度特性。刚度是衡量物体在外力作用下抵抗形变能力的一个重要指标,在管道设计中尤其关键,因为它直接影响到管道的稳定性和...

    管道通信命名管道通信

    管道通信是操作系统中进程间通信(IPC)的一种方式,尤其在UNIX系统中广泛使用。它分为两种类型:无名管道(匿名管道)和命名管道(FIFO)。 1. **无名管道通信**: 无名管道是半双工的(即数据只能单向流动),...

    进程的管道通信编制一段程序,实现进程的管道通信,使用系统调用pipe()建立一个管道文件;两个子进程P1和P2

    进程的管道通信 编制一段程序,实现进程的管道通信,使用系统调用pipe()建立一个管道文件;两个子进程P1和P2 分别向管道各写一句话: Child1 is sending a message! Child2 is sending a message! 而父进程则从...

    通风管道阻力计算

    通风管道阻力计算是暖通空调领域中的重要环节,它涉及到空气流动时在管道内部遇到的摩擦阻力和局部阻力。在设计和优化通风系统时,准确计算管道阻力至关重要,以确保空气能够有效地流通并达到预期的通风效果。下面将...

    动力管道手册.rar

    动力管道手册是一本涵盖广泛且深入的工程技术文献,主要针对工业和建筑领域的动力管道系统设计、施工、维护和管理。这个压缩包中的“动力管道手册.pdf”文件,很可能是全面介绍动力管道工程的专业资料,旨在为工程师...

    Threejs透明管道及流动液体效果相同的路径创建两条管道,一条用于透明管道,一条作为管道内流动的液体

    Threejs透明管道及流动液体效果使用相同的路径创建两条管道,一条用于透明管道,一条作为管道内流动的液体。需要注意的是,透明管道材质需要设置depthWrite=false;否则内部流动的液体会被遮挡无法显示。

    管道监测 智能小区智能管道

    **知识点生成:声学检测技术在燃气管道监测中的应用** 在智能小区的建设与管理中,燃气管道的安全监测是一项至关重要的任务。随着科技的发展,声学检测技术成为了管道监测领域的一项创新方法,尤其是在燃气管道的...

    建筑工程小程序 管道保温计算小软件

    建筑工程小程序 管道保温计算小软件建筑工程小程序 管道保温计算小软件建筑工程小程序 管道保温计算小软件建筑工程小程序 管道保温计算小软件建筑工程小程序 管道保温计算小软件建筑工程小程序 管道保温计算小软件...

Global site tag (gtag.js) - Google Analytics