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