IPC对象、消息队列 、共享内存

我要成为嵌入式高手之3月4日Linux高编第十四天!!

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

一、IPC对象

内存文件,如何查看?

1、ipcs:

        查看系统中的IP对象的消息队列、共享内存、信号灯信息

2、ipcrm:

        功能:删除消息队列或者共享内存或者信号灯

        ipcrm  -Q/-M/-S  key(ipc对象的名字)

        ipcrm  -q/-m/-s  消息队列的id/共享内存的id/信号灯的id

二、消息队列相关的函数接口

消息队列的操作流程:

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

1、ftok

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);

功能:根据pathname和porject id生成一个key_t类型的key值,可以用来创建消息队列、共享内存、信号灯

参数:

        pathname:文件路径

        proj_id:8位非0值

返回值:

        成功返回key_t类型的IPC对象的key值

        失败返回-1;

2、msgget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

功能:根据key值对应的IPC对象创建一个消息队列

参数:

        key:IPC对象的名字

        msgflg: IPC_CREAT        对象不存在创建

                       IPC_EXCL           对象存在报错

                       IPC_CREAT || 0664加权限

返回值:

        成功返回消息队列ID,失败返回-1;

3、msgsnd

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

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:存放接收到消息空间的首地址

         struct msgbuf {
               long mtype;       /* message type, must be > 0 */(消息的类型)
               char mtext[1];    /* message data */(消息的内容)
           };

        msgsz:最多接收消息空间的大小

        msgtyp:相要接收消息的类型

        msgflg:属性,默认填0

返回值:

        成功返回实际接受的字节数,失败返回-1;

5、msgctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

功能:向消息队列发送一条cmd命令

参数:

        msgqid:消息队列的id号

        cmd:命令:IPC_RMID 删除消息队列

         buf:默认传NULL

返回值:成功返回0,失败返回-1;

练习:

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

send.c

#include "head.h"struct msgbuf
{long mtype;char mtext[256];
};int main(void)
{key_t key;int msgid = 0;int ret = 0;ssize_t nret = 0;struct msgbuf sendmsg;char s[256] = {0};key = ftok(".", 's');//第二个参数是个8位非零值if (-1 == key){perror("fail to ftoksend");return -1;}msgid = msgget(key, IPC_CREAT | 0664);//向key对应的IPC对象创建一个消息队列if (-1 == msgid){perror("fail to msgget");return -1;}while (1){memset(&sendmsg, 0, sizeof(sendmsg));sendmsg.mtype = 100;//设定要发送的消息的类型fgets(sendmsg.mtext, sizeof(sendmsg.mtext), stdin);//strcpy(sendmsg.mtext, s);ret = msgsnd(msgid, &sendmsg, sizeof(struct msgbuf)-sizeof(long), 0);if (ret == -1){perror("fail to msgsnd");return -1;}if (!strcmp(sendmsg.mtext, ".quit\n")){break;}}msgctl(msgid, IPC_RMID, NULL);return 0;
}

recv.c

#include "head.h"struct msgbuf
{long mtype;char mtext[256];
};int main(void)
{key_t key;int msgid = 0;int ret = 0;ssize_t nret = 0;struct msgbuf recvmsg;char s[256] = {0};key = ftok(".", 's');//第二个参数是个8位非零值if (-1 == key){perror("fail to ftoksend");return -1;}msgid = msgget(key, IPC_CREAT | 0664);//向key对应的IPC对象创建一个消息队列if (-1 == msgid){perror("fail to msgget");return -1;}while (1){memset(&recvmsg, 0, sizeof(recvmsg));nret = msgrcv(msgid, &recvmsg, sizeof(struct msgbuf)-sizeof(long), 100, 0);if (ret == -1){perror("fail to msgrecv");return -1;}if (!strcmp(recvmsg.mtext, ".quit\n")){break;}printf("RECV: %s", recvmsg.mtext);}msgctl(msgid, IPC_RMID, NULL);return 0;
}

三、共享内存

进程间通信最高效的形式

1、操作方式

       创建共享内存 -> 让两个进程映射到共享内存中 -> 对共享内存做操作 -> 解除映射 -> 删除共享内存

2、函数接口

        1)ftok

        2)shmget

               #include <sys/ipc.h>
               #include <sys/shm.h>

               int shmget(key_t key, size_t size, int shmflg);

                功能:创建一个共享内存

                参数:

                        key:IPC对象的名称

                        size:共享内存的大小

                        shmflg:

                                IPC_CREAT

                                IPC_EXCL

                返回值:成功0,失败-1;

        3)shmat   

               #include <sys/types.h>
               #include <sys/shm.h>

               void *shmat(int shmid, const void *shmaddr, int shmflg);

                功能:将一个地址映射到共享内存中

                参数:

                        shmid:共享内存ID号

                        shmaddr:NULL让系统选择一个合适的地址映射

                                          不为NULL: shmflg设定为SHM_RND选择离给定的地址最近的能够
                                          映射的地址进行映射,否则传递地址为4k的整数倍

                        shmflg:标志位,0

                返回值:成功返回映射空间的地址,失败返回NULL

        4)shmdt

                int shmdt(const void *shmaddr);

                功能:解除映射

                参数:shmaddr映射的地址

                返回值:成功0,失败-1
        

        5)shmctl

               #include <sys/ipc.h>
               #include <sys/shm.h>

               int shmctl(int shmid, int cmd, struct shmid_ds *buf);

                功能:向共享内存发送命令

                参数:

                        shmid:共享内存ID号

                        cmd:IPC_RMID删除共享内存

                        buf:NULL

                返回值:成功返回0,失败返回-1

练习:

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

write.c

#include "head.h"int main(void)
{key_t key;int shmid = 0;char *p = NULL;key = ftok(".", 'a');if (key == -1){perror("fail to ftokshm");return -1;}shmid = shmget(key, 4096, IPC_CREAT | 0664);//第二个参数为共享内存空间大小if (shmid == -1){perror("fail to shmget");return -1;}p = (char *)shmat(shmid, NULL, 0);if (NULL == p){perror("fail to shmat");return -1;}while(1){gets(p);if (!strcmp(p, ".quit")){break;}}shmdt(p);shmctl(shmid, IPC_RMID, NULL);return 0;
}

read.c

#include "head.h"int main(void)
{key_t key;int shmid = 0;char *p = NULL;int cnt = 0;key = ftok(".", 'a');if (key == -1){perror("fail to ftokshm");return -1;}shmid = shmget(key, 4096, IPC_CREAT | 0664);//第二个参数为共享内存空间大小if (shmid == -1){perror("fail to shmget");return -1;}p = (char *)shmat(shmid, NULL, 0);if (NULL == p){perror("fail to shmat");return -1;}while(1){printf("SHM: %s\n", p);if (!strcmp(p, ".quit")){break;}}shmdt(p);shmctl(shmid, IPC_RMID, NULL);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/268702.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯倒计时 41天 - 二分答案-最大通过数-妮妮的月饼工厂

最大通过数 思路&#xff1a;假设左边能通过 x 关&#xff0c;右边能通过 y 关&#xff0c;x∈[0,n]&#xff0c;通过二分&#xff0c;在前缀和中枚举右边通过的关卡数&#xff0c;保存 xy 的最大值。 #include<bits/stdc.h> using namespace std; typedef long long ll…

产品营销展示型wordpress外贸网站模板

工艺品wordpress外贸主题 简约大气的wordpress外贸主题&#xff0c;适合做工艺品进出品外贸的公司官网使用。 https://www.jianzhanpress.com/?p5377 餐饮设备wordpress外贸主题 简洁的wordpress外贸主题&#xff0c;适合食品机械、餐饮设备公司使用。 https://www.jianzh…

洛谷 B3620 x 进制转 10 进制

题目描述 给一个小整数 x 和一个 x 进制的数 S。将 S 转为 10 进制数。对于超过十进制的数码&#xff0c;用 A&#xff0c;B&#xff0c;…… 表示。 输入格式 第一行一个整数 x; 第二行一个字符串 S。 输出格式 输出仅包含一个整数&#xff0c;表示答案。 输入输出样例…

leetcode 移除链表元素

本题中&#xff0c;我们是要移除链表的某一个节点&#xff0c;为了确保统一操作&#xff0c;我们需要使用虚拟头节点&#xff0c;这样我们删除节点的时候&#xff0c;就是把这个要删除的节点&#xff08;当前节点cur&#xff09;的前一个节点pre&#xff0c;使得pre.next指向要…

sqlserver保存微信Emoji表情

首先将数据库字段&#xff0c;设置类型为 nvarchar(200)一个emoji表情&#xff0c;占4字节就可以了&#xff0c;web前端展示不用改任何东西&#xff0c;直接提交数据保存&#xff1b;回显也会没有问题&#xff0c;C#代码不用做任何处理&#xff1b; 不哭不闹要睡觉&#x1f31…

执行一条 select 语句,期间发生了什么?

大家好我是苏麟 , 今天开始又开一个坑 MySQL原理 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 执行一条 select 语句&#xff0c;期间发生了什么&#xff1f; 学习 SQL 的时候&#xff0c;大家肯定第一个先学到的就是 select 查询语句了&#xff…

UCSF DOCK 分子对接详细案例(04)-基于RDKit描述符的分子从头设计DOCK_D3N

欢迎浏览我的CSND博客&#xff01; Blockbuater_drug …点击进入 文章目录 前言一、 软件及操作环境二、研究目的三、结构文件准备四、 DOCK/RDKit中 de novo design4.1 de novo design - refine_D3N4.2 对输出重新评分 总结参考资料 前言 本文是UCSF DOCK的使用案例分享&…

Windows服务器:通过nginx反向代理配置HTTPS、安装SSL证书

先看下效果&#xff1a; 原来的是 http&#xff0c;配置好后 https 也能用了&#xff0c;并且显示为安全链接。 首先需要 SSL证书 。 SSL 证书是跟域名绑定的&#xff0c;还有有效期。 windows 下双击可以查看相关信息。 下载的证书是分 Apache、IIS、Tomcat 和 Nginx 的。 我…

uniapp实现-审批流程效果

一、实现思路 需要要定义一个变量, 记录当前激活的步骤。通过数组的长度来循环数据&#xff0c;如果有就采用3元一次进行选择。 把循环里面的变量【name、status、time】, 全部替换为取出的那一项的值。然后继续下一次循环。 虚拟的数据都是请求来的, 组装为好渲染的格式。 二…

linux中对信号的认识

信号的概念与相关知识认识 信号是向目标进程发送消息通知的的一种机制。 信号可以以异步的方式发送给进程&#xff0c;也就是说&#xff0c;进程无需主动等待&#xff0c;而是在任何时间都可以接收到信号。 信号的种类 用kill-l命令查看系统定义的信号列表&#xff1a; 前台…

thinkphp学习11-数据库的查询表达式

比较查询 查询表达式支持大部分常用的 SQL 语句&#xff0c;语法格式如下 where(字段名,查询表达式,查询条件);在查询数据进行筛选时&#xff0c;我们采用 where()方法&#xff0c;比如 id79&#xff1b; $user1 Db::name(user)->where(id, 79)->find(); $user2 Db::…

巧用二进制实现俄罗斯方块小游戏

效果预览 思想 首先建立两个数组board、tetris用来存储当前已经堆积在棋盘的方块与正在下落的方块。 这两个是一维数组当需要在页面画棋盘时就对其每一项转成二进制&#xff08;看计算属性tetrisBoard&#xff09;&#xff0c;其中1&#xff08;红色&#xff09;0&#xff08;…

加密与安全_深入了解Hmac算法(消息认证码)

文章目录 PreHMAC概述常见的Hmac算法Code随机的key的生成 KeyGeneratorHmacMD5用Hmac算法取代原有的自定义的加盐算法 HmacMD5 VS MD5HmacSHA256 Pre 加密与安全_深入了解哈希算法中我们提到&#xff0c; 存储用户的哈希口令时&#xff0c;要加盐存储&#xff0c;目的就在于抵…

现货黄金价格今日行情怎样把握?

由于受到各种经济和政治因素的影响&#xff0c;国际市场上的黄金价格&#xff0c;每天的行情走势都在不断地波动&#xff0c;有时候行情上涨&#xff0c;有时候行情下跌&#xff0c;如果投资者不懂得灵活地应对&#xff0c;在哪一种行情中都有可能亏损&#xff0c;但如果投资者…

Linux系统CPU模式部署Qwen1.5-14B

Qwen1.5已适配Ollama。 Ollama 是一个命令行聊天机器人&#xff0c;它使得几乎可以在任何地方使用大型语言模型变得简单。 下载 Ollma 安装文件 访问以下网站&#xff1a;https://ollama.com/download/linux 执行&#xff1a;curl -fsSL https://ollama.com/install.sh | sh…

信息安全是什么

信息安全&#xff0c;也称为信息安全或数据安全&#xff0c;是防止未经授权的访问、更改、中断和破坏信息。 信息安全本身包括的范围很大&#xff0c;大到国家军事政治等机密安全&#xff0c;小范围的当然还包括如防范商业企业机密泄露&#xff0c;防范青少年对不良信息的浏览…

解决虚拟机启动报错:“End kernel panic - not syncing: attempted to kill the idle task”

原本能正常运行的虚拟机&#xff0c;很长一段时间没用后&#xff0c;今天再次启动&#xff0c;然后就出现下面的问题&#xff1a; 然后走了一些弯路&#xff0c;比如说删除该虚拟机然后新建一个虚拟机&#xff08;问题未解决&#xff09;、直接删除VitualBox重新安装&#xff0…

探索网络世界:IP代理与爬虫技术的全景解析

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

全新攻击面管理平台

首页大屏 内测阶段&#xff0c;免费试用一个月 有兴趣体验的师傅&#xff0c;来长亭云图极速版群里找我 py

0201sherlock(福尔摩斯)-通过名称寻找媒体账号(地址)-github-开源项目学习

文章目录 一 项目简介二 项目安装和演示1 安装2 演示 三 源码分析1 项目结构2 主程序源代码分析 四 添加自定义网址结语 一 项目简介 二 项目安装和演示 1 安装 # clone the repo $ git clone https://github.com/sherlock-project/sherlock.git# change the working direct…