目录
一:消息队列
1.1定义
消息队列是消息的链接表,存储在内核中,由消息队列标识符 标识。
1.2设计方案
如图所示:先调用msgget()获取一个已存在,或者 创建一个新的队列。A进程负责发送某一类型的数据,B进程负责接受相应类型的数据。
1.3知识了解
一:相关结构
①消息结构:
//假设发送的最长消息是512个字节
struct mymesg{
long mtype; /* positive message type */
char mtext[512]; /*message data, or length nbytes */
}
②每个消息队列都会维护一个相关数据结构: msqid_ds
//消息队列维护信息。
struct msqid_ds{
struct ipc_perm msg_perm; //权限控制
msgqnum_t msg_qnum; //消息队列消息数目
msglen_t msg_qbytes;//max # of bytes on queue
pid_t msg_lspid; //pid of last msgsnd()上一次发送消息的进程
pid_t msg_lrpid; //pid of lase msgrcv()上一次接受消息的进程
time_t msg_stime; //last_msgsnd() time
time_t msg_rtime; //last_ecvsnd() time
time_t msg_ctime; //last_change time
}
二:相关函数
①函数:msgget
头文件 函数原型: | #include<sys/msg.h> int msgget(key_t key,int flag) |
参数: | key:用于变换成一个标识符(ID) flag:权限,以及各种控制信息的指定。 |
功能: | 创建一个新队列或者打开一个现有队列。(主要是和其他函数配套使用,msgctl,msgsnd,msgrcv)。 |
函数返回值: | 成功返回消息队列ID,出错返回-1. |
②函数:msgctl
函数原型: | int msgctl ( int msgid, int cmd , struct msqid_ds *buf); |
函数参数: | 1 msgid :队列编号 2 cmd :(幻数),用于指定命令,IPC_STAT,IPC_SET,IPC_RMID. 3 buf:指向结构体的指针。 |
函数功能: | 对队列进行多种操作。 |
③函数:msgsnd
函数原型: | int msgsnd ( int msgid , const void* ptr , size_t nbytes , int flag) |
函数参数: | 1 msgid:队列编号 2 ptr :指向一个mesg的结构体(本结构体不是头文件提供的) 3 nbytes: 消息大小。 4 flag(幻数),用于指定命令,IPC_NOWAIT(非阻塞标志)。 |
函数功能和返回值: | 将数据发送到消息队列中: 成功返回0,失败返回-1. |
④函数:msgrcv
函数原型: | int msgrcv ( int msgid , void* ptr , size_t nbytes,long type , int flag); |
函数参数: | msgid 队列编号 ptr 指向一个mesg结构体指针 nbytes 消息大小 type 消息类型 flag(幻数) 用于制定命令,IPC_NOWAIT(非阻塞标志)。 |
函数功能和返回值: | 从消息队列中取数据。 成功,返回消息队列数据部分的长度,否则返回-1。 |
二:代码实现
2.1发送消息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>
typedef struct data
{
long type;
char text[512];
}Data;
int main()
{
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//获取
assert(msgid != -1);
Data val;
memset(&val, 0, sizeof(Data));
val.type = 1000;
strcpy(val.text, "hello");
msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
memset(&val, 0, sizeof(Data));
val.type = 2000;
strcpy(val.text, "world");
msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
exit(0);
}
2.2取用消息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>
typedef struct data
{
long type;
char text[512];
}Data;
int main()
{
int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
assert(msgid != -1);
Data val;
memset(&val, 0, sizeof(Data));
//char buff[128] = {0};
msgrcv(msgid, &val, sizeof(Data), 1000, 0);
printf("type = %d, text = %s\n", val.type, val.text);
exit(0);
}