进程通信学习笔记(System V消息队列)

来源:互联网 发布:windows找不到chrome 编辑:程序博客网 时间:2024/06/05 12:59

跟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;前一个用msgsnd()的进程id

pid_t msg_lrpid;前一个用msgrcv()的进程id

time_t msg_stime;前一个用msgsnd()的时间

time_t msg_rtime;前一个用msgrcv()的时间

time_t msg_ctime;前一个msgctl()的时间

};

1、msgget函数

用于创建一个新的消息队列或访问一个已存在的消息队列

#include <sys/msg.h>
int msgget(key_t key, int oflag);

成功返回非负标识符,失败返回-1

返回值是一个整数标识符,key可以是ftok的返回值 ,也可以是常值IPC_PRIVATE,oflag可以有MSG_R(0400),MSG_W(0200),MSG_R>>3(0040),MSG_W>>3(0020),MSG_R>>6(0004),MSG_W(0002),也可以与IPC_CREAT和IPC_EXCL按位或

MSG_R:用户(属主)读

MSG_W:用户(属主)写

MSG_R>>3:由(属)组成员读

MSG_W>>3:由(属)组成员写

MSG_R>>6:由其他用户读

MSG_W>>6:由其他用户写

当创建一个新的消息队列时,msqid_ds结构的如下成员被初始化:

(1)msg_perm结构的uid和cuid成员被设置成当前进程的有效用户ID,gid和cgid成员被设置成当前进程的有效组ID

(2)oflags中的读写权限位存放在msg_perm.mode中

(3)msg_qnum,msg_lspid,msg_lrpid,msg_stime,msg_rtime被置为0

(4)msg_ctime被设置成当前时间

(5)msg_qbytes被设置成系统限制值


2、msgsnd函数

往队列中放入一个消息

#include <sys/msg.h>
int msgsnd(int msqid, const void *ptr, size_t length, int flag);

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

ptr是一个结构指针,该结构有如下模板,定义在<sys/msg.h>中

struct msgbuf

{

long mbyte;  消息类型

char mtext[1];  消息数据

};

消息类型要大于0

flag参数可以是0,也可以是IPC_NOWAIT。IPC_NOWAIT标志使得msgsnd调用非阻塞,如果没有存放消息的可有空间,函数立即返回。发生情况包括:

(1)在队列中已有太多的字节 msqid_ds结构中的msg_qbytes

(2)在系统范围存在太多的消息

如果这两个条件中有一个存在,而且IPC_NOWAIT标志已指定,msgsnd返回一个EAGAIN错误


3、msgrcv函数

从队列中读出一个消息

#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *ptr, size_t length, long byte, int flag);

成功返回读入缓冲区数据的字节数,失败返回-1

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

(1)type == 0,返回该队列中的第一个消息

(2)type > 0,返回类型值为type的第一个消息

(3)type < 0,返回类型值<=type参数的绝对值的消息中类型值最小的第一个消息

flag指定所请求的消息不在队列时的处理。在没有消息可得的情况下,如果设置了IPC_NOWAIT位,立即返回一个ENOMSG错误,否则阻塞到下列某个事件发生为止

(1)有一个所请求类型的消息可获取

(2)由msqid标识的消息队列被从系统中删除

(3)调用线程被某个捕获的信号所中断

flag参数中另有一位可以指定MSG_NOERROR,当所接收消息的真正数据部分大于length参数时,如果设置了该位,msgrcv函数只是截短数据部分,而不返回错误,否则,返回一个E2BIG错误


4、msgctrl函数

在消息队列上的控制操作

#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buff);

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

有三个命令:

(1)IPC_RMID:从系统中删除msqid指定的消息队列。当前在该队列上的任何消息都被丢弃

(2)IPC_SET:给队列设置其中的msqid_ds结构的四个成员:msg_perm.uid, msg_perm.gid, msg_perm.mode和msg_qbytes

(3)IPC_STAT:给调用者返回指定队列的当前msqid_ds结构


0 0