当前位置: 首页 > article >正文

嵌入式学习——进程间通信方式(1)——有名管道和匿名管道

一、基本概念

我们要知道管道为什么叫做管道,管道就好比我们生活中的水管,水总是从一端流向另一端,你总不能从水龙头往里灌水吧,它只能出水。管道也是类似的,数据从管子的一端传入,在另一端进行数据的读取。

什么是管道?当数据从一个进程流到另一个进程时,他们连接就是通过管道(pipe)来实现的,

这也就是它的工作模式是半双工通信。

二、匿名管道

基本的使用流程:        

        1)创建管道文件

              int  pipe(int pipefd[2]);

              0索引代表读端,1索引代表写端

        2)进行读/写管道文件

              read(int pipefd[0]);
              write(int pipefd[1]);

        3)关闭管道文件

              close(int pipefd[2]);

特点:

        1)只能用于具有亲缘关系的进程之间进行通信。

        2)不会在文件系统中体现出一个文件,只存在于内存中。

        3)它是半双工的通信模式(具有固定的读端和写端,如果要互相传送数据,需要构建两个管道)

注意:管道文件创建不能在共享文件夹下

举例:父进程往管道文件写数据,子进程读取父进程写入管道文件的数据

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>                                                                                                                                                                                       
int main()
{
        int pipefd[2] = {0};
        int ret = pipe(pipefd);
        if(ret == -1) 
        {
            perror("pipe failed");
            return -1; 
        }
        //创建子进程
        pid_t pid = fork();
        if(pid == 0)
        {
            //从管道读取数据
            char buff[20] = {0};
            read(pipefd[0],buff,20);
            printf("从管道读取的数据是:%s\n",buff);
            exit(0);
        }else if(pid > 0)
        {
            //往管道写入数据
            char buff[20] = "Hello,myson";
            write(pipefd[1],buff,sizeof(buff));
        }else
        {
            printf("create pid failed");
        }
        close(pipefd[0]);
        close(pipefd[1]);
        wait(NULL);
        return 0;
}

三、有名管道

基本的使用流程:

        1)创建管道文件

              int mkfifo(const char *pathname, mode_t mode);
              第一个是创建管道文件的路径及其名称
              第二个是管道文件的权限

        2)打开管道文件

              int open(const char *pathname, int flags);

        3)读/写管道文件

              read();  / write();

        4)关闭管道文件

              close();

        5)销毁管道文件

              int unlink(const char *pathname);

特点:

        1)可以在不同的进程中相互进行通信,不需要具有亲缘关系的进程,也可以在具有亲缘关系的进程中使用。

        2)会在文件系统中体现出一个文件,即管道文件(注意:管道文件在Windows不存在,所以不能在共享文件夹中创建管道文件)。

        3)管道文件仅仅是文件系统中的标示,并不在磁盘上占据空间。在使用时,在内存上开辟空间,作为两个进程数据交互的通道。

举例:两个不同进程进行管道通信,一个进程发送数据,另一个进程接收数据

发送的进程:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
                                                                                                                                                                                                            
int main()
{
        int ret = mkfifo("./pipe",0644);
        if(ret == -1) 
        {
            perror("create pipe failed");
            return -1; 
        }
        int fd = open("./pipe",O_WRONLY);
        if(fd == -1) 
        {
            perror("open pipe failed");
            return -1; 
        }

        char buff[20] = "Hello,myfriend!";
        write(fd,buff,sizeof(buff));

        close(fd);


        return 0;
}

接收的进程:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
        int fd = open("./pipe",O_RDONLY);
        if(fd == -1) 
        {
            perror("open pipe failed");
            return -1; 
        }

        char buff[20] = {0};
        read(fd,buff,sizeof(buff));

        printf("收到的信息是:%s\n",buff);

        close(fd);                                                                                                                                                                                          

        unlink("./pipe");

        return 0;
}

                        

四、匿名管道和有名管道的区别

       1)相同点:open打开管道文件以后,在内存中开辟了一块空间,管道的内容在内存中存放,读写数据都是在给内存的操作,并且都是半双工通讯。

        2)不同点:有名在任意进程之间使用,无名在父子进程之间使用。

        


http://www.kler.cn/news/321441.html

相关文章:

  • 高频 SQL 50 题(基础版)| 180. 连续出现的数字
  • The Open Group 2024生态系统架构·可持续发展年度大会全面解读
  • 企业微信AI社群助手:赋能企业私域运营的新引擎
  • JAVA集成Jasypt进行加密、解密(SpringBoot)
  • 【ARM 嵌入式 编译系列 10.4 -- GNU Binary Utilies】
  • python测试开发---前后端交互Axios
  • 利用 ARMxy边缘计算网关和 BLiotlink 软网关,实现工业智能化升级
  • VB.NET中如何利用ADO.NET Entity Framework进行ORM(对象关系映射)
  • 在Mac电脑上安装adb环境
  • npm 安装newman时idealTree:vue: sill idealTree buildDeps卡住了(实测成功)
  • 初识C语言(三)
  • VC++同时处理ANSI和Unicode字符集,除了使用TCHAR和_T()宏外,还有其他方法可以实现吗?
  • 【含文档】基于Springboot+微信小程序 的高校社团管理小程序(含源码+数据库+lw)
  • fastdfs开源分布式文件系统及迁移部署
  • mvnd 初体验
  • 探索5 大 Node.js 功能
  • 【递归】7. leetcode 404 左叶子之和
  • 宠物浮毛难清理,希喂、小米、美的宠物空气净化器该选哪款?
  • 深度学习:自然语言处理的基本原理
  • sqlserver迁移数据库文件存储位置
  • Java2 实用教程(第6版)习题2 第四题
  • Python | Leetcode Python题解之第438题找到字符串中所有字母异位词
  • 负载均衡SLB详解及其应用场景
  • 2024 Fortinet OT工业安全高峰论坛成功举办
  • 【yolov7】模型导出----pytorch导出为onnx模型
  • MacOS关闭,最小化窗口快捷键
  • Go基础学习06-Golang标准库container/list(双向链表)深入讲解;延迟初始化技术;Element;List;Ring
  • Java | Leetcode Java题解之第440题字典序的第K小数字
  • OIDC5-OIDC 的工作流程
  • 详解机器学习经典模型(原理及应用)——GBDT