社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
目录
System V消息队列使用消息队列标识符标识,和Posix消息队列一样,发送消息和接收消息的线程(进程)是相互独立、互不依赖的。
对于系统中的每个消息队列,内核维护一个定义在sys/msg.h头文件中的结构,其中带注释的是我们需要关注的成员变量。
struct msqid_ds
{
struct ipc_perm msg_perm;
struct msg *msg_first; //指向队列中第一条消息
struct msg *msg_last; //指向队列中最后一条消息
msglen_t msg_cbytes; //消息队列当前第几个字节
msgqnum_t msg_qnum; //消息队列当前第几条消息
msglen_t msg_qbytes; //消息队列允许的最大字节数,仅针对消息数据,不包括与每个消息关联的长整型消息类型
pid_t msg_lspid;
pid_t msg_lrpid;
time_t msg_stime;a
time_t msg_rtime;
time_t msg_ctime;
};
msgget用于创建一个新的消息队列或访问一个已存在的消息队列,参数key和oflag的含义及使用方法和semget一样,不再赘述。
//成功返回消息队列标识符,失败返回-1
int msgget(key_t key, int oflag);
msgsnd用于向消息队列中添加一条消息。
//成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t length, int flag);
参数说明:
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
msgrcv用于从消息队列中取出一条消息。
//成功返回实际读入缓冲区的数据长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t length, long type, int flag);
参数说明:
msgrcv第四个参数type用于指定希望从消息队列中读出什么样的消息,假设有消息队列中有三条消息:
那么:
msgctl提供在一个消息队列上的各种控制操作。
//成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl支持三个cmd命令:
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define FTOK_FILE "/home/delphi/ftok.file"
#define FTOK_ID 1
#define MSG_RD_PERMISSION 0444
#define MSG_WR_PERMISSION 0222
#define MSG_RW_PERMISSION (MSG_RD_PERMISSION | MSG_WR_PERMISSION)
#define MAX_MSG_LEN (8192 + sizeof(long))
struct msgbuf
{
long type;
char *data;
};
#endif
#include "common.h"
int main()
{
key_t key = ftok(FTOK_FILE, FTOK_ID);
int oflag = IPC_CREAT | MSG_RW_PERMISSION;
int msgid = msgget(key, oflag);
if (msgid >= 0)
{
printf("msgget create success, msgid = %dn", msgid);
}
return 0;
}
#include "common.h"
int main(int argc, char **argv)
{
int msgid;
int msglen;
long msgtype;
struct msgbuf *msg;
msgid = msgget(ftok(FTOK_FILE, FTOK_ID), MSG_WR_PERMISSION);
msglen = atoi(argv[1]);
msgtype = atol(argv[2]);
msg = (struct msgbuf *)calloc(sizeof(long) + msglen, sizeof(char));
msg->type = msgtype;
msgsnd(msgid, msg, msglen, 0);
return 0;
}
#include "common.h"
int main(int argc, char **argv)
{
int msgid;
int rcvlen;
long msgtype;
struct msgbuf *msg;
msgid = msgget(ftok(FTOK_FILE, FTOK_ID), MSG_RD_PERMISSION);
msgtype = atol(argv[1]);
msg = (struct msgbuf *)calloc(MAX_MSG_LEN, 1);
rcvlen = msgrcv(msgid, msg, MAX_MSG_LEN, msgtype, 0);
printf("read %d bytes, type = %ldn", rcvlen, msg->type);
return 0;
}
#include "common.h"
int main(int argc, char **argv)
{
int msgid = msgget(ftok(FTOK_FILE, FTOK_ID), 0);
msgctl(msgid, IPC_RMID, 0);
return 0;
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!