进程间通信->消息队列

Posted studying~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信->消息队列相关的知识,希望对你有一定的参考价值。

消息队列,是消息的链表,存放在内核中。每个消息队列都有一个标识符(即队列ID)来标识。
1、特点
消息队列是面向记录的,其中的消息具有特定的格式(内容)以及特定的优先级(类型)。
消息队列由内核管控,与进程无关。进程终止时,消息队列及其内容并不会被删除。
消息队列(链表)支持消息的随机查询,也支持按消息的类型读取。

2、原型

1 #include <sys/msg.h>
2 // 创建或打开消息队列:成功返回队列ID,失败返回-1
3 int msgget(key_t key, int flag);
4 // 添加消息:成功返回0,失败返回-1
5 int msgsnd(int msqid, const void *ptr, size_t size, int flag);
6 // 读取消息:成功返回消息数据的长度,失败返回-1
7 int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
8 // 控制消息队列:成功返回0,失败返回-1
9 int msgctl(int msqid, int cmd, struct msqid_ds *buf);
10 #include <sys/types.h>
11 #include <sys/ipc.h>
12 key_t ftok( const char * fname, int id )

参数说明:
msgget
key:索引值,双方通过同个key找到同个队列进行数据交互
key可以在自己写(整数)也可以由键值格式转换函数ftok获取
fname:一般使用当前目录,如:key_t key = ftok(".", 1); 这样就是将fname设为当前目录。

flag:队列权限
在以下两种情况下,msgget将创建一个新的消息队列:

1.如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。
2.key参数为IPC_PRIVATE。

msgrcv
type:消息的类型
函数msgrcv在读取消息队列时,type参数有下面几种情况:

type == 0,返回队列中的第一个消息;
type > 0,返回队列中消息类型为 type 的第一个消息;
type < 0,返回队列中消息类型值小于或等于 type 绝对值的消息,如果有多个,则取类型值最小的消息。
可以看出,type值非 0 时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值。(其他的参数解释,请自行Google之)

flag:默认(写0)情况下,读不到这种类型的消息会阻塞
msgctl
cmd:指令,通常写IPC_RMID,意思是将消息队列从内核中移除
buf:通常写NULL

代码案例

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };

int main()
{
   struct msgbuf sendbuf={.mtype = 988,.mtext = "hello world"};
   struct msgbuf readbuf={.mtext=0};
   key_t key = ftok(".",1);
   int msgid = msgget(key,0777|IPC_CREAT);
   if(msgid == -1)
   {
      printf("open/create msgget fail\\n");
      exit(0);
   }
   msgrcv(msgid, &readbuf, sizeof(readbuf.mtext), 888, 0);
   printf("type = %ld,readbuf = %s\\n",readbuf.mtype,readbuf.mtext);
   msgsnd(msgid, &sendbuf, strlen(sendbuf.mtext), 0);
   return 0;
}         
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <string.h>
struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };

int main()
{
   struct msgbuf readbuf={.mtext=0};
   struct msgbuf sendbuf={.mtype = 888,.mtext = "hello world"};
   key_t key = ftok(".",1);
   int msgid = msgget(key,0777|IPC_CREAT);
   if(msgid == -1)
   {
      printf("open/create msgget fail\\n");
      exit(0);
   }
   msgsnd(msgid, &sendbuf, strlen(sendbuf.mtext), 0);
   msgrcv(msgid, &readbuf, sizeof(readbuf.mtext), 988, 0);
   printf("type = %ld,readbuf = %s\\n",readbuf.mtype,readbuf.mtext);
   return 0;
}

在这里插入图片描述

以上是关于进程间通信->消息队列的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信——消息队列

八进程间通信-消息队列

Linux进程间通信——消息队列

Linux C语言高级编程之使用消息队列实现进程间通信!重点内容!!!

Linux进程间通信之消息队列

linux进程间通信之消息队列