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

嵌入式学习 Day 30

消息队列、共享内存、信号灯:

1.IPC对象(内存文件)

    1.ipcs 

      查看系统重的消息队列、共享内存、信号灯的信息


    2.ipcrm

      删除消息队列、共享内存、信号灯
      ipcrm -Q/-M/-S key
      ipcrm -q/-m/-s 消息队列ID/共享内存ID/信号灯ID

2.消息队列


    1.操作流程:

        创建消息队列 -> 发送消息 -> 接收消息

    2.函数接口:

        1.ftok

          key_t ftok(const char *pathname, int proj_id);
          功能:
            根据pathname和proj_id生成一个key_t类型的key值,将来可以用来创建消息队列、共享内存、信号灯
          参数:
            pathname:文件路径
            proj_id:8位非0值
          返回值:
            成功返回key_t类型的IPC对象的key值
            失败返回-1 

        2.msgget 

          int msgget(key_t key, int msgflg);
          功能:
            根据key值对象的IPC对象创建一个消息队列
          参数:
            key:IPC对象名字 
            msgflg:IPC_CREAT    对象不存在就创建
                   IPC_EXCL     对象存在报错
                   IPC_CREAT | 0664 
          返回值:
            成功返回消息队列ID
            失败返回-1 

        3.msgsnd 

          int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
          功能:
            向消息队列中发送消息
          参数:
            msqid:消息队列的ID号
            msgp:发送消息空间的首地址
                struct msgbuf {
                    long mtype;       /* message type, must be > 0 */
                    char mtext[1];    /* message data */
                };
            msgz:发送消息内容的大小(不包含发送消息类型)
            msgflg:属性,默认为0
          返回值:
            成功返回0 
            失败返回-1 

        4.msgrcv 

          ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
          功能:
            从消息队列中接收消息
          参数:
            msqid:消息队列的ID号 
            msgp:存放接收到消息空间的首地址
            msgsz:最多接收消息的空间的大小
            msgtyp:想要接收消息的类型
            msgflg:属性,默认为0 
          返回值:
            成功返回实际接收的字节数
            失败返回-1 

        5.msgctl 

          int msgctl(int msqid, int cmd, struct msqid_ds *buf);
          功能:
            向消息队列发送一条cmd命令
          参数:
            msqid:消息队列的ID号
            cmd:IPC_RMID    删除消息队列 
            buf:默认传NULL
          返回值:
            成功返回0 
            失败返回-1 

练习:编写2个进程任务(recv.c send.c),send.c从终端接收一个字符串利用消息队列发送给recv.c,recv.c从消息队列中接收消息并打印在终端

2.共享内存:


    进程间通信最高效的形式

    1.操作方式:

        创建共享内存 -> 映射到共享内存中 -> 共享内存操作 -> 解除映射 -> 删除共享内存 

    2.函数接口:
        1.ftok 
        

        2.shmget 

          int shmget(key_t key, size_t size, int shmflg);
          功能:
            创建一个共享内存
          参数:
            key:IPC对象名称
            size:共享内存的大小
            shmflg:
                IPC_CREAT 
                IPC_EXCL 
          返回值:  
            成功返回共享内存ID
            失败返回-1 
        

        3.shmat

          void *shmat(int shmid, const void *shmaddr, int shmflg);
          功能:
            将一个地址映射到共享内存中
          参数:
            shmid:共享内存ID号
            shmaddr:NULL     让系统选择一个合适的地址映射
                    不为NULL shmflg 设定为SHM_RND 选择离给定地址最近的能够映射的地址进行映射
                             否则传递地址为4k的整数倍
          返回值:
            成功返回映射到共享内存空间中的地址
            失败返回NULL

        4.shmdt 

          int shmdt(const void *shmaddr);
          功能:
            解除映射 
          参数:
            shmaddr:映射的地址
          返回值:
            成功返回0 
            失败返回-1 

        5.shmctl

          int shmctl(int shmid, int cmd, struct shmid_ds *buf);
          功能:
            向共享内存发送命令
          参数:
            shmid:共享内存ID号
            cmd:IPC_RMID    删除共享内存
            buf:NULL 
          返回值:
            成功返回0 
            失败返回-1 

练习:编写2个进程任务,write.c负责从终端接收字符串写入共享内存中,read.c负责将共享内存中的数据打印在终端

3.信号灯 (有名信号量)


    1.创建

        semget 
        int semget(key_t key, int nsems, int semflg);
        功能:
            创建一组信号量
        参数:
            key:IPC对象名
            nsems:信号量的个数
            semflg:IPC_CREAT 
        返回值:
            成功返回信号量ID
            失败返回-1 

    2.销毁 

        semctl
        int semctl(int semid, int semnum, int cmd, ...);
        功能:   
            向信号灯发送命令
        参数:
            semid:信号灯ID号
            semnum:具体操作信号量的编号
            cmd:
                IPC_RMID    删除信号灯
                SETVAL      设置信号量的值
        返回值:
            成功返回0
            失败返回-1 

        初始化:
        union semun {
            int              val;    /* Value for SETVAL */
            struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
            unsigned short  *array;  /* Array for GETALL, SETALL */
            struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                        (Linux-specific) */
        };

    3.申请信号量

    4.释放信号量

        semop 
        int semop(int semid, struct sembuf *sops, size_t nsops);
        功能:
            对信号量完成操作
        参数:
            semid:信号灯的ID号
            sops:信号量操作的数组首地址
            nsops:数组元素个数
        返回值:
            成功返回0 
            失败返回-1 

         unsigned short sem_num;  /* semaphore number */        操作信号量的下标
         short          sem_op;   /* semaphore operation */     具体对信号量的操作(申请:-1  释放:+1)
         short          sem_flg;  /* operation flags */         SEM_UNDO


 

相关文章:

  • 部署DNS解析服务
  • 【比较mybatis、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp操作数据】操作批量新增、分页查询(四)
  • 数据分析-Pandas数据y轴双坐标设置
  • Oracle.xs.dll‘ for module DBD::Oracle: load_file:找不到指定的模块
  • Unity 学习笔记索引
  • 使用模拟器接入互联网
  • Android项目开发如何设计整体架构,重磅消息
  • html标签之表格标签,资料分享
  • 学习JAVA的第十二天(基础)
  • 磁性机器人在医学领域取得进展
  • ROS读书记录1:机器人SLAM导航核心技术与实战1
  • MongoDB获评2023年Gartner®云数据库管理系统“领导者”
  • iOS应用内购安全:生成共享密钥以验证收据+核对凭证内不能伪造的字段【解决IAP收据伪造问题】
  • Redis面试问题纯享版
  • android高级面试2020,淘汰了80%的Android面试者
  • JavaScript 如何正确处理 Unicode 编码问题!
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • [Vue CLI 3] 配置解析之 css.extract
  • __proto__ 和 prototype的关系
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Android 架构优化~MVP 架构改造
  • go append函数以及写入
  • Java读取Properties文件的六种方法
  • js继承的实现方法
  • js如何打印object对象
  • Linux中的硬链接与软链接
  • mac修复ab及siege安装
  • MaxCompute访问TableStore(OTS) 数据
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 猴子数据域名防封接口降低小说被封的风险
  • 基于webpack 的 vue 多页架构
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 王永庆:技术创新改变教育未来
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • 湖北分布式智能数据采集方法有哪些?
  • 昨天1024程序员节,我故意写了个死循环~
  • ​什么是bug?bug的源头在哪里?
  • !!java web学习笔记(一到五)
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (2)STM32单片机上位机
  • (层次遍历)104. 二叉树的最大深度
  • (论文阅读11/100)Fast R-CNN
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .net MySql
  • .Net Web项目创建比较不错的参考文章
  • .NET 反射的使用
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径