UNIX(进程间通信):10 消息队列 您所在的位置:网站首页 消息队列中的消息可以随机查询 UNIX(进程间通信):10 消息队列

UNIX(进程间通信):10 消息队列

2024-05-02 16:45| 来源: 网络整理| 查看: 265

一、消息队列的特点

1.消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识. 2.消息队列允许一个或多个进程向它写入与读取消息. 3.管道和命名管道都是通信数据都是先进先出的原则。 4.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。

目前主要有两种类型的消息队列:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。系统V消息队列是随内核持续的,只有在内核重起或者人工删除时,该消息队列才会被删除。

二、相关函数

1. 获得key值

key_t ftok(char *pathname, int projid)

#include #include 参数: pathname:文件名(含路径),通常设置为当前目录“.” 比如projid为'a',则为"./a"文件 projid:项目ID,必须为非0整数(0-255).

2. 创建消息队列 int msgget(key_t key, int msgflag) #include #include #include 功能: 用于创建一个新的或打开一个已经存在的消息队列,此消息队列与key相对应。 参数: key:函数ftok的返回值或IPC_PRIVATE。 msgflag: IPC_CREAT:创建新的消息队列。 IPC_EXCL:与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误。 IPC_NOWAIT:读写消息队列要求无法满足时,不阻塞。 返回值: 调用成功返回队列标识符,否则返回-1.

在以下两种情况下,将创建一个新的消息队列: 1、如果没有与键值key相对应的消息队列,并且msgflag中包含了IPC_CREAT标志位。 2、key参数为IPC_PRIVATE。

3. 消息队列属性控制 int msgctl(int msqid, int cmd, struct msqid_ds *buf) 功能: 对消息队列进行各种控制操作,操作的动作由cmd控制。 参数: msqid:消息队列ID,消息队列标识符,该值为msgget创建消息队列的返回值。 cmd: IPC_STAT:将msqid相关的数据结构中各个元素的当前值存入到由buf指向的结构中. IPC_SET:将msqid相关的数据结构中的元素设置为由buf指向的结构中的对应值. IPC_RMID:删除由msqid指示的消息队列,将它从系统中删除并破坏相关数据结构. buf:消息队列缓冲区

代码语言:javascript复制 struct msqid_ds { struct ipc_perm msg_perm; /* Ownership and permissions*/ time_t msg_stime; /* Time of last msgsnd() */ time_t msg_rtime; /* Time of last msgrcv() */ time_t msg_ctime; /* Time of last change */ unsigned long __msg_cbytes; /* Current number of bytes in queue (non-standard) */ msgqnum_t msg_qnum; /* Current number of messages in queue */ msglen_t msg_qbytes; /* Maximum number of bytesallowed in queue */ pid_t msg_lspid; /* PID of last msgsnd() */ pid_t msg_lrpid; /* PID of last msgrcv() */ }; struct ipc_perm { key_t key; /* Key supplied to msgget() */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions */ unsigned short seq; /* Sequence number */ };

4.发送信息到消息队列 int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflag) #include #include #include 功能:

将新消息添加到队列尾端,即向消息队列中发送一条消息。 参数: msqid:已打开的消息队列id msgp:存放消息的结构体指针。 msgflag:函数的控制属性。 消息结构msgbuf为: struct msgbuf { long mtype;//消息类型 char mtext[1];//消息正文,消息数据的首地址,这个数据的最大长度为8012吧,又可把他看成是一个结构,也有类型和数据,recv时解析即可。 } msgsz:消息数据的长度。 msgflag: IPC_NOWAIT: 指明在消息队列没有足够空间容纳要发送的消息时,msgsnd立即返回。 0:msgsnd调用阻塞直到条件满足为止.(一般选这个)

5. 从消息队列接收信息 ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtype, int msgflag) #include #include #include 功能:

从队列中接收消息 参数: msqid:已打开的消息队列id msgp:存放消息的结构体指针。msgp->mtype与第四个参数是相同的。 msgsz:消息的字节数,指定mtext的大小。 msgtype:消息类型,消息类型 mtype的值。如果为0,则接受该队列中的第一条信息,如果小于0,则接受小于该值的绝对值的消息类型,如果大于0,接受指定类型的消息,即该值消息。 msgflag:函数的控制属性。 msgflag: MSG_NOERROR:若返回的消息比nbytes字节多,则消息就会截短到nbytes字节,且不通知消息发送进程. IPC_NOWAIT:调用进程会立即返回.若没有收到消息则返回-1. 0:msgrcv调用阻塞直到条件满足为止. 在成功地读取了一条消息以后,队列中的这条消息将被删除。

三、相关例子

例1:消息队列之简单收发测试

代码语言:javascript复制#include #include #include #include #include struct msg_buf{ int mtype;//消息类型 char data[255];//数据 }; int main(int argc, char *argv[]) { key_t key; int msgid; int ret; struct msg_buf msgbuf; //获取key值 key = ftok(".", 'a'); printf("key = [%x]\n", key); //创建消息队列 msgid = msgget(key, IPC_CREAT|0666);/*通过文件对应*/ if(msgid == -1) { printf("creat error\n"); return -1; } //以当前进程类型,非阻塞方式发送"test data"到消息队列 msgbuf.mtype = getpid(); strcpy(msgbuf.data, "test data"); ret = msgsnd(msgid, &msgbuf, sizeof(msgbuf.data), IPC_NOWAIT); if(ret == -1) { printf("send message err\n"); return -1; } //以非阻塞方式接收数据 memset(&msgbuf, 0, sizeof(msgbuf)); ret = msgrcv(msgid, &msgbuf, sizeof(msgbuf.data), getpid(), IPC_NOWAIT); if(ret == -1) { printf("receive message err\n"); return -1; } printf("receive msg = [%s]\n", msgbuf.data); return 0; }

例2:进程间消息队列通信

代码语言:javascript复制#include #include #include #include #include #include struct msgbuf{ int mtype; char mtext[100]; }; int main(void) { key_t key; pid_t pid; int msgid; struct msgbuf msg; key=ftok(".", 0x01); if ( (msgid = msgget(key, IPC_CREAT|0666))


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有