管道

作者: 荷叶的莲藕 | 来源:发表于2019-02-02 18:23 被阅读0次

管道

image.png
//pipedemo
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

//管道有一个读取端一个写入端

main()
{
    int len,i,apipe[2];
    char buf[BUFSIZ];
    
    if(pipe(apipe) == -1){
        perror("could not make pipe");
        exit(1);
    }
    printf("Got a pipe ! It is fiile descriptors:{%d %d}\n",apipe[0],apipe[1]);
    
    //read from stdin ,write into pipe ,read from pipe,print
    
    while(fgets(buf,BUFSIZ,stdin)){//进程从标准输入读数据,数据存在buf
        len = strlen(buf);
        printf("%d\n",len);
        if(write(apipe[1],buf,len)!=len){//把数据写到管道的写入端
            perror("writing to pipe");
            break;
        }
        
        for(i = 0;i<len;i++)//清理buf
            buf[i] = 'X';
        len = read(apipe[0],buf,BUFSIZ);//从管道的读取端读取数据到buf
        
        if(len == -1){
            perror("reading from pipe");
            break;
        }
        if(write(1,buf,len)!=len){//把buf的数据输出到标准输出
            perror("writing to stdout");
            break;
        }
    }
}

管道有一个读取端,一个写入端,当一个进程创建了一个管道之后,该进程就有了连向管道两端的连接。这个进程调用fork的时候,他的子进程也得到了这两个连向管道的连接,父进程和子进程都可以将数据写到管道的写数据端口,并从读数据端口将数据读出,两个进程都可以读写管道,但是当一个进程读,一个进程写的时候,管道的使用效率是最高的。

image.png

下面的程序就是pipe与fork结合起来,创建一堆通过管道来通信的进程。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#define CHILD_MESS "I want a cookie\n"
#define PAR_MESS "testing..\n"
#define oops(m,x)   {perror(m);exit(x);}

main()
{
    int pipefd[2];
    int len;
    char buf[BUFSIZ];
    int read_len;
    
    if(pipe(pipefd) == -1)
        oops("cannot get a pipe",1);
    
    switch(fork()){
        case -1:
            oops("cannot fork",2);
        case 0:
            len = strlen(CHILD_MESS);
            while(1){
                if(write(pipefd[1],CHILD_MESS,len)!=len)
                    oops("write",3);
                sleep(5);
                
            }
            //parent reads from pipe and also writes to pipe
        default:
            len = strlen(PAR_MESS);
            while(1){
                if(write(pipefd[1],PAR_MESS,len)!=len)
                    oops("write",4);
                sleep(1);
                read_len = read(pipefd[0],buf,BUFSIZ);
                if(read_len <=0)
                    break;
                write(1,buf,read_len);
            }
    }
}

总结

管道在许多方面类似于普通文件,进程使用write将数据写入管道,又通过read把数据读出来。像文件一样,管道是不带有任何结构的字节序列。另一方面,管道又与文件不同。

1.主要内容 ·输入/输出重定向允许完成特定功能的程序通过交换数据来进行相互协作。 • Unix 默认规定程序从文件描述符 0 读取数据,写数据到文件描述符1,将错误信息输 出到文件描述符 2 。这三个文件描述符称为标准输入、输出及标准错误输出。 ·当登录到 Unix 系统中,登录程序设置文件描述符 0 、 1 、 2 。所有的连接、文件描述符 都会从父进程传递给子进程。它们也会在调用 exec 时被传递。 ·创建文件描述符的系统调用总是使用最低可用文件描述符号。 • 322 • Unix/Linux 编程实践教程 ·重定向标准输入、输出以及错误输出意味着改变文件描述符 0 ,1- 2 的连接。有很多 种技术来重定向标准l/O 。 ·管道是内核中的一个数据队列,其每一端连接一个文件描述符。程序通过使用 plpe 系统调用创建管道。 .当父进程调用 fork 的时候,管道的两端都被复制到子进程中。 .只有有共同父进程的进程之间才可以用管道连接。

相关文章

  • 工业管道工程施工程序

    管道分类与分级 工业管道按压力分级 管道的组成 管道由管道组成件和管道支承件组成 管道组件管道组成件是用于连接或装...

  • 管道基础

    ##管道基础 #通信分类:只写单工管道、只读单工管道、半双工管道(单向读写)、全双工管道(两个半双工管道拼接) 类...

  • Linux 进程间通信

    进程间通信 一 进程间通信 -- 管道 mkfifo test 创建管道文件 匿名管道和命名管道:匿名管道:匿名管...

  • 隧道安全逃生管道最新成果

    新型高分子隧道安全逃生管道分别有高分子逃生管道、新型隧道逃生管道、轻型逃生管道、悬挂式隧道逃生管道、防腐逃生管道、...

  • Linux-C-day-2-进程通过--管道通信

    管道通信 进程间管道通信方式可以通过man 7 pipe来查看; 匿名管道 单工管道 打开管道:使用popen()...

  • Redis管道技术的使用

    目录 Redis 管道技术 SpringDataRedis 使用管道 Redis 管道的性能测试 使用管道技术的注...

  • 进程间通信方式

    管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字...

  • Linux进程间的通信

    管道,命名管道,信号

  • 建筑管道工程施工技术

    分类 按输送介质划分:给水管道、排水管道、供 暖管道、热水管道、空调水管道等。 施工程序 建筑管道施工程序 :施工...

  • 管道---无名管道

    无名管道的特点: 1:无名管道只能用于具有亲缘关系的进程之间的通信(这里理解为,二叉树中只有具有同一...

网友评论

      本文标题:管道

      本文链接:https://www.haomeiwen.com/subject/ivzssqtx.html