msgget 系统调用
使用
- 创建一个消息
- 获得一个消息描述符
- 核心搜索消息队列头表
- 若无: 核心分配新的消息队列头表, 并初始化, 然后返回消息队列描述符
- 若有, 检查消息队列的许可权便返回
函数原型
msgqid = msgget(key,flag)
对应头文件
参数定义
key:指定的消息队列名
flag:设置标志和访问方式
- IPC_CREATE |0400 是否该队列已被创建
- IPC_EXCL|0400 是否该队列的创建时互斥的
megsnd
使用
- 向指定消息队列发送消息
- 并将该消息链接到消息队列的尾部
函数原型
msgsnd(msgqid,msgp.size,flag)
头文件
#include <sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
参数定义
msgqid:
消息队列的描述符
msgp:
指向消息缓冲区的结构体指针
size:
- mtext字符数组的长度, 即消息的长度
flag:
- 规定核心用尽时内部缓冲对应的操作
- 未设置IPC_NOWAIT:
进程进入睡眠
- 设置IPC_NOWAIT:
msgsnd立即返回
对应核心操作
- 检查小队列的描述符和许可证记忆消息长度, 不合法则返回
- 核心为消息分配消息数据区,消息正文拷贝到消息数据区
- 分配消息头部, 并链入消息队列末尾
- 修改消息队列头中的数据. 如队列中的消息数、字节总数等
- 唤醒等待消息的进程
msgrcv
使用
从指定消息队列中接受指定类型的消息
函数原型
msgrcv(msgqid,msgp,size,type,flag)
头文件
#include <sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
参数定义
除了type, 其他的与msgsnd相似
type:
- 指定要读懂消息类型
flag:
- 在消息队列中无消息时
- - 1. 设置了IPC_NOWAIT: 立即返回
- - 2.设置MS_NOERROR, 若接受消息大于size , 核心截断所接受的消息
核心操作
- 对消息队列的描述符和许可证检查
- 根据消息type分情况处理
2.1.type=0,接收该队列的第一个消息,并将它返回给调用
2.2 type 为正整数,接收类型 type 的第一个消息
2.3.type 为负整数,接收小于等于 type 绝对值的最低类型的第一个消息
mgsctl
- 消息队列的操作
- 读取消息队列的状态信息并修改
函数原型
msgctl(msgqid,cmd,buf);
int msgqid,cmd;
struct msgqidds *buf
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.
参数定义
- 返回值, 成返回0, 不成功返回-1
- cmd参数
- 对应结构体
实践演示
客户端
#include <stdlib.h>/*{{{*/
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>/*}}}*/
#define MSGKEY 75
struct msgform
{
long mtype;// message type
char mtext[1000];//message text
}msg;
int msgqid;//message descriptor
void client()
{
int i;
/** int msgget(key_t key, int msgflg); */
msgqid = msgget(MSGKEY,0777);// open 75# message quequ
for(i = 10; i >=1; i--)
{
msg.mtype = i;
printf("(client) sent\n");
/** int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); */
/** If (msgflg & IPC_NOWAIT) is 0, the calling thread shall suspend execution */
msgsnd(msgqid,&msg,1024,0); // send message, will sleep when kernal run-out
}
exit(0);
}
int main()
{
client();
}
服务端
#include <stdlib.h>/*{{{*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>/*}}}*/
#define MSGKEY 75
struct msgform
{
long mtype;
char mtext[1000];
}msg;
int msgqid;
void server()
{
//A message queue identifier, associated message queue, and data structure{{{
//(see <sys/msg.h>), shall be created for the argument key if one of the fol‐
//lowing is true:
//
// * The argument key is equal to IPC_PRIVATE.
//
// * The argument key does not already have a message queue identifier asso‐
// ciated with it, and (msgflg & IPC_CREAT) is non-zero.}}}
msgqid = msgget(MSGKEY,0777|IPC_CREAT);// create 75# message queqe
do
{
/** ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); */
if (-1 == msgrcv(msgqid,&msg,1030,0,0)){
continue;
printf("(server)no message received\n");
sleep(1);
}
printf("(server)received\n");
}while(msg.mtype!=1);// break UNTILL mtype == 1
// IPC_RMID Remove the message queue identifier specified by msqid from the system and destroy the message queue and msqid_ds data structure associated with it.{{{
// IPC_RMD can only be executed by a process with appropriate privileges or one that has an effective user ID equal to the value of msg_perm.cuid or
// msg_perm.uid in the msqid_ds data structure associated with msqid.}}}
msgctl(msgqid,IPC_RMID,0);
exit(0);
}
int main()
{
server();
}