Linux学习笔记之9(消息队列)

Linux learning

1、引言

消息队列(message queue)也是进程之间通信的一种方式,相比于共享内存的通信方式,消息队列也有类型的运行机制,也是在多个进程之间开辟一个内存区域,让不同进程可以访问。由于消息队列其实是通过拷贝数据的方式来储存数据的,所以效率上比共享内存低,但优点在于消息队列可以通过函数来对内存中的数据进行排序等操作。

查看系统中是否存在消息队列,可以在终端中输入一下命令。

bash 复制代码
ipcs -q

2、创建一个消息队列

创建一个消息队列用到的函数是msgget(),其函数原型如下:

c 复制代码
int msgget(key_t key, int msgflg);

可以在shell中输入"man 2 msgget"查看其更详细的信息。

  • key:键值,可以由自己指定,也可以用ftok()函数生成,相当于给这个消息队列取一个独一无二的名字,以便于其他进程访问。
  • msgflg:指定消息队列的权限。
  • return:成功则返回消息队列的标识符,失败则返回-1。

3、发送和接受消息

3.1、发送消息

发送消息用的是msgsnd()函数,其原型如下:

c 复制代码
int  msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
  • msgid:消息队列的id,其实就是msgget()函数的返回值。
  • msg_ptr:存储消息的内存指针。这里要求必须是一个格式如下的结构体。
c 复制代码
typedef struct
{
	long mtype;
	char mtext[8];			//数组的小大可以自己指定
}Msg_buf;
  • msg_sz:上述结构体中mtext的长度。
  • msgflg:指定在达到系统为消息队列限定的界限时应采取的操作。 Linux的官方说明书中有这样一段话。

If insufficient space is available in the queue, then the default behavior of msgsnd() is to block until space becomes available. If IPC_NOWAIT is specified in msgflg, then the call instead fails with the error EAGAIN.

即意味着,默认情况下,如果消息队列达到上限的时候,默认的操作是让该函数进入阻塞。而如果msgflg被设定为IPC_NOWAIT,则如果达到上限,那么直接抛出报错信息。

  • return:成功则返回0,失败则返回-1。

3.1、接收消息

读取消息用到的函数是msgrcv(),其原型如下。

c 复制代码
int  msgrcv(int msgid, void *msg_ptr, size_t msgsz, long int msgtype, int msgflg);
  • msqid:消息队列标识符,也是msgget的返回值。
  • msg_ptr:指向用户自定义的缓冲区,也是指向一个结构与上文所诉一样的结构体。(但注意它和发送消息函数所用的结构体并不共享同一块内存)
  • msgsz:也是指结构体中的mtext的长度。
  • msgtype:指定请求的消息类型:
    • msgtyp=0:收到的第一条消息,任意类型。
    • msgtyp>0:收到的第一条msgtyp类型的消息。
    • msgtyp<0:收到的第一条最低类型(小于或等于msgtyp的绝对值)的消息。
  • msgflg:有两个选项可以选,IPC_NOWAIT和IPC_NOERROR。前者指示函数,没有消息则无需等待,返回ENOMSG的报错即可。后者指示函数,当个消息大小超过msgsz时,舍弃超出的部分。
  • return:成功返回0,失败返回-1。

4、删除一个消息队列

删除一个消息队列用到了msgctl()函数,从msgctl英语全称应是message control也可以窥视到,该函数应当不仅仅只有函数消息队列一个功能。事实上,它可以对消息队列的基本属性进行控制、修改。其函数原型如下:

c 复制代码
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • msqid:消息队列标识符,也是msgget的返回值。
  • cmd:控制和修改消息队列。
    • IPC_RMID:删除消息队列,立即生效。
    • IPC_SET:设置消息队列的属性。
    • IPC_STAT:读取消息队列的属性。
    • IPC_INFO:读取消息队列的基本情况。
  • buf:结构很复杂,作为初学者,我暂时不像深入学习。一般我用的时候直接设置为0即可。

5、例程

相关推荐
dengqingrui1233 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
热爱嵌入式的小许3 小时前
Linux基础项目开发1:量产工具——显示系统
linux·运维·服务器·韦东山量产工具
我的心永远是冰冰哒3 小时前
ad.concat()学习
学习
ZZZ_O^O3 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
slomay5 小时前
关于对比学习(简单整理
经验分享·深度学习·学习·机器学习
hengzhepa5 小时前
ElasticSearch备考 -- Async search
大数据·学习·elasticsearch·搜索引擎·es
小小洋洋7 小时前
BLE MESH学习1-基于沁恒CH582学习
学习
韩楚风7 小时前
【linux 多进程并发】linux进程状态与生命周期各阶段转换,进程状态查看分析,助力高性能优化
linux·服务器·性能优化·架构·gnu
陈苏同学7 小时前
4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
linux·服务器·ide·人工智能·python·深度学习·pycharm
Ambition_LAO7 小时前
解决:进入 WSL(Windows Subsystem for Linux)以及将 PyCharm 2024 连接到 WSL
linux·pycharm