linux system v消息队列,System V消息队列

1. 概述

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;

};

2. 消息队列api

msgget

msgget用于创建一个新的消息队列或访问一个已存在的消息队列,参数key和oflag的含义及使用方法和semget一样,不再赘述。

//成功返回消息队列标识符,失败返回-1

int msgget(key_t key, int oflag);

msgsnd

msgsnd用于向消息队列中添加一条消息。

//成功返回0,失败返回-1

int msgsnd(int msqid, const void *ptr, size_t length, int flag);

参数说明:

msqid是msgget返回的标识符

ptr是一个由应用程序按如下模板定义的struct sembuf结构指针,只要保证第一个成员变量是long type即可,其后的数据部分可根据需要任意扩展

struct msgbuf

{

long mtype; /* message type, must be > 0 */

char mtext[1]; /* message data */

};

length是待发送消息的长度,即消息类型之后的用户自定义数据的长度,该长度可以是0

flag可以是0或者ipc_nowait,一般设为0

msgrcv

msgrcv用于从消息队列中取出一条消息。

//成功返回实际读入缓冲区的数据长度,失败返回-1

int msgrcv(int msqid, void *ptr, size_t length, long type, int flag);

参数说明:

msqid是msgget返回的标识符

ptr指向数据接收缓冲区,它应该和msgsnd的ptr具有同样的struct sembuf结构

length为缓冲区大小

type用于指定希望从消息队列中读出什么样的消息

flag可以是0、ipc_nowait或msg_noerror,一般设为0

msgrcv第四个参数type用于指定希望从消息队列中读出什么样的消息,假设有消息队列中有三条消息:

第一条消息的类型为100,长度为1

第二条消息的类型为200,长度为2

第二条消息的类型为300,长度为3

那么:

type = 0:返回队列中第一个消息

type > 0:返回消息类型等于type的第一个消息

type < 0:返回消息类型 <= abs(type)的消息中类型值最小的第一个消息

e6207a858442ab8c015c0e6eca775350.png

msgctl

msgctl提供在一个消息队列上的各种控制操作。

//成功返回0,失败返回-1

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

msgctl支持三个cmd命令:

ipc_rmid:从系统中删除由msqid指定的消息队列,此时第三个参数被忽略,设为null即可

ipc_stat:通过buf参数返回由msqid指定消息队列对应的msqid_ds结构

ipc_set:通过buf参数返回由msqid指定消息队列对应的msqid_ds结构,但仅设置以下4个成员:msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_perm.qbytes

3. 简单的程序

代码实现

common.h

#ifndef _common_h_

#define _common_h_

#include

#include

#include

#include

#include

#include

#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

msgcreate.c

#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 = %d\n", msgid);

}

return 0;

}

msgsnd.c

#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;

}

msgrcv.c

#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 = %ld\n", rcvlen, msg->type);

return 0;

}

msgrmid.c

#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;

}

代码测试

a709e1c1806f4d5612e383754f124867.png

a4cddb661be57d2a077dc5962ba2deef.png

95dc98dab883accbe09a7ea845f39a36.png

44c2aa8671783f7d0203e20bd49d9882.png

39b88ba9dc91b90d8dc7d00738822ab2.png

8006189692b0a907d240e7e3c793da92.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值