0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

阐述匿名管道和命名管道

汽车电子技术 来源:wenzi嵌入式软件 作者: wenzid 2023-01-20 17:17 次阅读

概述

管道是 UNIX系统 IPC的最古老的形式,所有的UNIX系统都提供此种通信。所谓的管道,也就是内核里面的一串缓存,从管道的一段写入的数据,实际上是缓存在内核中的,令一端读取,也就是从内核中读取这段数据。对于管道传输的数据是无格式的流且大小受限。对于管道来说,也分为匿名管道和命名管道,其中命名管道也被叫做 FIFO,下面则分别阐述这两种管道。

匿名管道

微信截图_20230105161930.png

默认情况下,在 Shell命令执行过程中,任何一个命令都有一个标准输入设备(键盘)、标准输出设备(显示器)和标准输出设备(显示器),使用管道"|"可以将两个命令连接起来,从而改变标准的输入输出方式,下面是在 Linux 端运行命令行的一个截图:

微信截图_20230105161930.png

上述命令中的意思也就是,将ls命令得到的结果作为 grep tags命令的输入。

连接输入输出的中间设备即为一个管道文件,综上,也就是说使用管道可以将一个命令的输出作为另一个命令的输入(在运行的时候,一个命令将创建一个进程),而这种管道是临时的,命令执行完毕之后就会自动消失,这类管道称为 无名管道

匿名管道例子

匿名管道在使用前要先创建,其函数的声明如下:

extern int pipe (int __pipedes[2]);

此函数的参数是一个整型数组,如果执行成功,pipe 将存储两个整型文件描述符于__pipedes[0]__pipedes[1]中,他们分别指向管道的两端。如果系统调用失败,则返回 -1。

读无名管道,该函数的声明如下:

extern ssize_t read (int __fd, void *__buf, size_t __nbytes);

第一个参数fd为打开的文件描述符,buf为读出数据的存储位置,nbytes为读取数据的大小,调用 read 函数将从 fd 指向的文件描述符指定的打开文件中宏读 n 字节到 buf 指向的缓冲区内。

如果试图向已经填满的管道写入,系统会自动阻塞。一个管道不能同时被两个进程打开。

extern ssize_ t write(int __fd, __const void *__buf, size_t __n);

buf指向的缓冲区中向管道中写入nbytes字节,且每次写入的内容都附件在管道的末端。

微信截图_20230105161930.png

那要如何使用管道在两个进程之间通信呢,我们可以使用 fork()创建子进程,创建的子进程会复制父进程的文件描述符,这样就做到了两个进程各有两个fd[0]与fd[1],两个进程就可以通过各自的fd写入和读取同一个管道文件实现进程通信了,具体原理如下所示:

具体的例子如下所示:

#include
#include
#include

int main(int argc, char *argv[])
{
    pid_t pid;
    int temp;
    int pipedes[2];
    char s[14] = "test message!";
    char d[14];

    if (pipe(pipedes) == -1) // 创建管道
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if (pid == fork() == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)      // 子进程
    {
        printf("now,write data to pipe\\n");
        if (write(pipedes[1], s, 14) == -1)   // 写数据到管道
        {
            perror("write");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("the written data is:%s\\n",s);
            exit(EXIT_SUCESS);
        }
    }
    else if (pid > 0)     // 父进程
    {
        slepp(2);
        printf("now, read from pipe\\n");
        if ((read(pipedes[0], d, 14)) == -1)
        {
            perror("read");
            exit(EXIT_FAILURE);
        }
        printf("the data from pipe is:%s\\n",d);
    }
    return 0;
}

微信截图_20230105161930.png

代码运行的结果如下所示:

命名管道

命名管道又被称之为是 FIFO ,未命名的管道只能在两个相关的进程之间使用,而且这两个相关的进程还要又一个共同创建了他们的祖先进程,但是,通过 FIFO ,不相关的进程也能交换数据。

首先,介绍下是如何创建命名管道的:

extern int mkfifo (__const char *__path, __mode_t __mode);

mkfifo会根据参数建立特殊的有名管道文件,该文件必须不存在,而参数mode为该文件的权限。

下面是一个使用命名管道进行进程间通信的例子,例子分为两个程序,分别是读部分和写部分,首先看先往管道写数据的代码,代码如下所示:

#include  
#include  
#include  
#include  
#include  
#include  

int main() 
{ 
    int fd; 

    // FIFO file path 
    char * myfifo = "/tmp/myfifo"; 

    // Creating the named file(FIFO) 
    // mkfifo(, ) 
    mkfifo(myfifo, 0666); 

    char arr1[80], arr2[80]; 
    while (1) 
    { 
        // Open FIFO for write only 
        fd = open(myfifo, O_WRONLY); 
        printf("The fd is:%d\\n",fd);

        // Take an input arr2ing from user. 
        // 80 is maximum length 
        fgets(arr2, 80, stdin); 

        // Write the input arr2ing on FIFO 
        // and close it 
        write(fd, arr2, strlen(arr2)+1); 
        close(fd); 

        // Open FIFO for Read only 
        fd = open(myfifo, O_RDONLY); 

        // Read from FIFO 
        read(fd, arr1, sizeof(arr1)); 

        // Print the read message 
        printf("User2: %s", arr1); 
        close(fd); 
    } 
    return 0; 
}

然后是先往管道读数据的代码,代码如下所示:

微信截图_20230105161930.png

#include  
#include  
#include  
#include  
#include  
#include  

int main() 
{ 
    int fd1; 

    // FIFO file path 
    char * myfifo = "/tmp/myfifo"; 

    char str1[80], str2[80]; 
    while (1) 
    { 
        // First open in read only and read 
        fd1 = open(myfifo,O_RDONLY); 
        printf("The fd is:%d\\n",fd1);
        read(fd1, str1, 80); 

        // Print the read string and close 
        printf("User1: %s", str1); 
        close(fd1); 

        // Now open in write mode and write 
        // string taken from user. 
        fd1 = open(myfifo,O_WRONLY); 
        fgets(str2, 80, stdin); 
        write(fd1, str2, strlen(str2)+1); 
        close(fd1); 
    } 
    return 0; 
}

下面是代码运行的一个结果:

说明一下,就是说当运行 write程序的时候,会创建fifo文件,命名管道,然后,在 write文件中就执行open操作,但是,这里存在的一个问题就是,因为在运行 write程序的时候,没有进程打开读端,也就阻塞了 open函数的运行,只有运行read操作,以读的方式读取管道的数据,这样才能使得write中的open函数继续执行。

综上,也就是命名管道在进程中通信的一个例子。

小结

上述就是本次进程通信中关于管道的相关内容,其中就包括匿名管道以及命名管道,他们之间存在着差别吗,也各有各的应用,本次的分享就到这里啦~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • UNIX
    +关注

    关注

    0

    文章

    295

    浏览量

    41060
  • 管道
    +关注

    关注

    3

    文章

    144

    浏览量

    17813
  • IPC
    IPC
    +关注

    关注

    3

    文章

    306

    浏览量

    51348
收藏 人收藏

    评论

    相关推荐

    Linux匿名管道命名管道的区别

    数据。对于管道传输的数据是无格式的流且大小受限。对于管道来说,也分为匿名管道命名管道,其中
    发表于 10-12 12:50 793次阅读

    Linux下进程间通信方式-管道

    Linux下进程间通信方式-管道分享到: 本文关键字: linux 管道通信,linux 进程通信方式 ,无名管道,有名管道 管道是Lin
    发表于 08-29 15:29

    标准流管道

    华清远见嵌入式linux学习资料《标准流管道》,1.标准流管道函数说明 。与Linux的文件操作中有基于文件流的标准I/O操作一样,管道的操作也支持基于文件流的模式。这种基于文件流的管道
    发表于 09-09 14:13

    无名管道系统调用

    `华清远见嵌入式linux学习资料《无名管道系统调用》, 1.管道创建与关闭说明。管道是基于文件描述符的通信方式,当一个管道建立时它会创建两个文件描述符fd[0]和fd,其中fd[0]
    发表于 09-09 14:17

    命名管道FIFO读写规则

    Linux命名管道FIFO的读写规则《Linux程序设计(第3版)》对于Linux命名管道的读写规则详解的不够详细和清楚,查了些资料,在此总结一下: 1.从FIFO中读取数据:约定:如
    发表于 09-24 10:49

    匿名管道是什么?有何功能?

    这是我第一次出教程,若不好可在评论回复我哦(・。・)~~~~~注:匿名管道是一个未命名的单相管道,通常用来在一个父进程和一个子进程之间的传输数据。
    发表于 07-09 07:26

    无名管道的通信方式简介

    最常用的无名管道,有名管道,消息队列,信号,信号量,共享内存等进程间的通信方式。其实后面网络通信套字节 socket的方式也可以归为进程通行。1.无名管道 pipe从 UNIX 系统开始,无名
    发表于 11-04 09:03

    怎样通过匿名管道去实现进程间的通信呢

    进程通信是指什么?怎样通过匿名管道去实现进程间的通信呢?有哪些步骤?
    发表于 12-24 06:45

    有名管道的相关资料分享

    进程间通信在实际项目中多多少少都会使用到,最常用的有无名管道,有名管道,消息队列,信号,信号量,共享内存等进程间的通信方式。网络通信套字节 socket的方式也可以归为进程通行。无名管道只能用于有
    发表于 12-24 08:08

    RT-Thread的管道有什么特点呢?怎么去使用

    一. 什么是管道pipe: 匿名管道。对于熟悉 linux 开发的人来说,pipe 就很熟悉了。pipe 是一种 IPC 机制,他的作用是用作有血缘进程间完成数据传递,只能从一端写入,从另外一端读出
    发表于 04-14 14:57

    水暧管道工实用手册

    本书较全面系统地阐述了水暖管道所必备的知识与安装的基本技术。内容包括:水暖管道工的基本知识,常用工具,常用器材,基本操作技术,室内外管道安装,工业
    发表于 04-15 10:09 0次下载
    水暧<b class='flag-5'>管道</b>工实用手册

    Linux中的管道命名管道介绍

    在 Linux 中,pipe 能让你将一个命令的输出发送给另一个命令。管道,如它的名称那样,能重定向一个进程的标准输出、输入和错误到另一个进程,以便于进一步处理。
    的头像 发表于 09-23 10:33 3769次阅读
    Linux中的<b class='flag-5'>管道</b>和<b class='flag-5'>命名</b><b class='flag-5'>管道</b>介绍

    管道检测机器人助力管道检查 专治管道堵塞

    管道作为一种重要的社会基础建设设施,其应用范围极为广泛。管道在使用过程中,由于各种因素的影响,会产生各种各样的管道堵塞与管道故障和损伤。如果不及时的对
    发表于 03-14 17:16 1946次阅读

    管道机器人解决管道检测现有困境

    管道检测机器人是一种新型的管道检测技术,解决了传统管道检测存在的问题。相比较传统的管道进行检测技术方法及人力资源物力浪费,CCTV管道系统检
    的头像 发表于 08-08 14:51 2434次阅读
    <b class='flag-5'>管道</b>机器人解决<b class='flag-5'>管道</b>检测现有困境

    使用匿名管道技术获取CMD命令的执行结果

    远程 CMD 是指恶意程序接收到控制端发送的 CMD 指令后,在本地执行 CMD 命令,并将执行结果回传至控制端。本文将演示使用匿名管道技术获取 CMD 命令的执行结果。
    的头像 发表于 04-03 18:04 2359次阅读