千家信息网

Linux中消息队列的使用方式

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要讲解了"Linux中消息队列的使用方式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Linux中消息队列的使用方式"吧!1 消息队列的概念
千家信息网最后更新 2026年11月03日Linux中消息队列的使用方式

这篇文章主要讲解了"Linux中消息队列的使用方式",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Linux中消息队列的使用方式"吧!

1 消息队列的概念及使用过程

1)消息队列的概念

消息队列就是一个消息的链表。一条消息可以看作一个数据记录,此数据具有特定的格式。

进程可以按照特定的规则向队列中添加(写入)消息;其他的进程则可以从消息队列中读走消息。

2)消息队列的应用场景

消息队列本身就是IPC通信中的内容,所以它主要用于进程间的通信。

消息有读写,所以发送的消息可以用于动作的通知信号,也可以接收数据然后做其他处理。

2 消息队列相关的结构及函数

0)消息队列相关的结构

每个队列都有一个msqid_ds结构与其相关联,结构如下。

struct msqid_ds  {      struct ipc_perm msg_perm;     // 消息队列的存取权限以及其他一些信息                          time_t          msg_stime;    // 最近一次队列接受消息的时间      time_t          msg_rtime;    // 最近一次从队列中取出消息的时间      time_t          msg_ctime;    // 最近一次队列发生改动的时间      unsigned long   __msg_cbytes; // 队列中消息的占用内存的字节数      msgqnum_t       msg_qnum;     // 队列中当前的消息数      msglen_t        msg_qbytes;   // 队列所占用内存的最大字节数      pid_t           msg_lspid;    // 最近一次向队列发送消息的进程的pid msgsnd      pid_t           msg_lrpid;    // 最近一次从队列中取出消息的进程的pid };
struct ipc_perm {      key_t key;      ushort uid;         // 用户id,有效的用户ID和有效的组id(euid和egid)       ushort gid;      ushort cuid;        // 创建者的euid和egid       ushort cgid;      ushort mode;        // 访问模式参见模式标志       ushort seq;         // IPC对象使用频率信息 };

1)msgget函数

msgget函数用于创建或打开消息队列。

① 函数原型。

int msgget(key_t key,int msgflg)

② 头文件。

include    include    include 

③ 参数。

key:键值。

msgflg:打开标志。IPC_CREAT:表明新创建的一个消息队列。

④ 返回值。

成功:返回消息队列的id。

失败:-1。

2)msgsnd函数

msgsnd函数用于发送消息,即写消息到消息队列。

① 函数原型。

int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg)

② 头文件。

include    include    include 

③ 参数。

msgid:消息队列的id。

msgp:指向要发送的消息。

msgsz:消息的长度。

msgflg:标志位。

④ 返回值。

成功:0。

失败:-1。

3)msgrcv函数

msgrcv函数用于读消息队列,即从消息队列接收消息。

① 函数原型。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)  ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,intmsgflg)

② 头文件。

#include    #include   #include 

③ 参数。

msqid:消息队列的id。

msgp:存放消息。

msgsz:希望取到的消息的最大长度。

msgtyp:消息的类型,分下面三种情况:

当 msgtyp = 0:忽略类型,直接取队列中的第一条消息。

当 msgtyp > 0: 取消息队列中类型等于msgtyp的第一条消息。

当 msgtyp < 0: 取类型比msgtyp的绝对值要小或等于的消息,如果有多条消息

满足该条件,取类型最小的一条。

④ 返回值。

成功:实际接收到的消息的数据长度。

失败:-1。

4)msgctl函数

msgctl函数用于操作消息队列,比如进行消息队列的删除等等。

① 函数原型。

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

② 头文件。

#include   #include    #include 

③ 参数。

msqid:消息队列的id。

cmd:消息队列的操作命令,此参数指定对msqid指定的队列要执行的命令。

IPC_STAT:取此队列的msqidds结构,并将它存放在buf指向的结构中。

IPCSET:将字段msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_qbytes从buf指向的结构复制到与这个队列相关的msqid_ds结构中。

此命令只能由下列两种进程执行:

一种是其有效用户ID等于msg_perm.cuid或msg perm.uid。

另一种是具有超级用户特权的进程。只有超级用户才能增加msg_qbytes的值。

IPC_RMID:从系统中删除该消息队列以及仍在该队列中的所有数据。这种删除立即生效。

仍在使用这一消息队列的其他进程在它们下一次试图对此队列进行操作时,将得到EIDRM错误。

此命令只能由下列两种进程执行:

一种是其有效用户ID等于msg_perm.cuid或msg_perm.uid。

另一种是具有超级用户特权的进程。这3条命令(IPC_STAT、IPC_SET和IPC_RMID)也可用于信号量和共享存储。

buf:获取内核中的msqid_ds结构,通常不用。

④ 返回值。

成功:0。

失败:-1。

3 实例代码

下面用两个进程,给大家演示下消息队列的使用过程。

实例代码如下,说明都在代码注释中了,图片。

SendQueue.c。

#include #include #include #include #include  // 消息结构体 struct msg {       long msgtype;       //消息的类型       char msgtext[1024]; //消息的长度 };   void main(int argc, char *argv[]) {       int msgid;       char str[256];       struct msg msgst;          key_t key = ftok("/tmp",600);        //创建消息队列        msgid = msgget(key,0666 | IPC_CREAT);        //键盘输入消息       while(1)       {                    //获取消息数据             printf("\nPlease enter a message to send,input 'end' to quit!\n\n");             scanf("%s",str);              strcpy(msgst.msgtext,str);                  if(strncmp(str, "end", 3) == 0)             {                   printf("\n");                   break;             }              //发送消息             msgsnd(msgid,&msgst,sizeof(struct msg),0);       }         //输出消息队列        msgctl(msgid,IPC_RMID,0); }

ReceiveQueue.c。

#include  #include  #include  #include  #include  #include   // 消息结构体 struct msg {       long msgtype;       char msgtext[1024]; };     int main(int argc, char *argv[]) {       int RunFlag = 1;                         // 循环标志       int msgid = -1;                          // 消息id       long msgtp = 0;                          // 消息类型         struct msg msgst;                        // 消息结构体变量         key_t key = ftok("/tmp",600);            // 创建一个键值         msgid = msgget(key, 0666 | IPC_CREAT);   //建立消息队列         if(msgid == -1)       {             exit(1);                           // 异常退出       }           while(RunFlag)                           // 从队列中获取消息,直到遇到end消息为止       {             if(msgrcv(msgid,&msgst,sizeof(struct msg), msgtp, 0) == -1)             {                   exit(1);                     // 异常退出             }             printf("\nThe message received is: %s\n\n",msgst.msgtext);                   if(strncmp(msgst.msgtext, "end", 3) == 0) // 遇到end结束             {                   RunFlag = 0;                // 置退出循环标志             }           }           if(msgctl(msgid, IPC_RMID, 0) == -1)    // 删除消息队列       {             exit(1);                          // 异常退出       }               exit(0);                                // 正常退出 }

编译程序,先运行接收程序,再运行发送程序,输入要发送的消息,退出输入end。

① 两个终端运行结果如下:

② 单个终端运行结果如下:

感谢各位的阅读,以上就是"Linux中消息队列的使用方式"的内容了,经过本文的学习后,相信大家对Linux中消息队列的使用方式这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

消息 队列 函数 结构 进程 用户 类型 数据 参数 命令 标志 方式 有效 成功 原型 文件 长度 运行 代码 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京路客互联网科技有限公司 科技和互联网公司 互联网科技有限公司经营范围 中国 科技 互联网 西安互联网科技 杭州互联网科技公司 奇酷互联网科技公司 互联网科技革命 凡科互联网科技 卫星互联网科技股票 哈尔滨新华互联网科技学院 重庆互联网医院沙龙医盟信息科技 电子科技大学互联网创业大赛 洛阳共同富裕互联网科技有限公司 翼展科技 首家互联网医院 广州千川互联网科技有限公司 35岁以上互联网科技行业 陕西彩京云互联网科技有限公司 东风日产互联网科技公司叫什么 颐高云石互联网科技 云之行互联网科技 互联网金融 金融科技 互联网科技论坛 安控科技rtu产品工业互联网 彤创互联网科技有限公司 昊天互联网科技有限公司 烟台灵鸽互联网科技有限公司 信承诺互联网科技有限公司 第三届互联网大会安防黑科技 互联网科技创业有什么好项目
0