Linux IPC实践(7)

1.创建/获取一个消息队列

#include <fcntl.h>/* For O_* constants */#include <sys/stat.h>/* For mode constants */#include <mqueue.h>mqd_t mq_open(const char *name, int oflag);//专用于打开一个消息队列mqd_t mq_open(const char *name, int oflag, mode_t mode,struct mq_attr *attr);

参数:

name:消息队列名字;

oflag:与open函数类型,可以是O_RDONLY,O_WRONLY,O_RDWR,还可以按位或上O_CREAT,O_EXCL,O_NONBLOCK.

mode:如果oflag指定了O_CREAT,需要指定mode参数;

attr:指定消息队列的属性;

返回值:

成功:返回消息队列文件描述符;

失败:返回-1;

注意-PosixIPC名字限制:

1.必须以”/”开头,并且后面不能还有”/”,形如:/file-name;

2.名字长度不能超过NAME_MAX

3.链接时:Linkwith-lrt.

/**SystemV消息队列

通过msgget来创建/打开消息队列

intmsgget(key_tkey,intmsgflg);

**/

2.关闭一个消息队列

int mq_close(mqd_t mqdes);/** System V 消息队列没有类似的该函数调用**/

3.删除一个消息队列

int mq_unlink(const char *name);/** System V 消息队列通过msgctl函数, 并将cmd指定为IPC_RMID来实现int msgctl(int msqid, int cmd, struct msqid_ds *buf);**///示例int main(){mqd_t mqid = mq_open("/abc", O_CREAT|O_RDONLY, 0666, NULL);if (mqid == -1)err_exit("mq_open error");cout << "mq_open success" << endl;mq_close(mqid);mq_unlink("/abc");cout << "unlink success" << endl;}

4.获取/设置消息队列属性

int mq_getattr(mqd_t mqdes, struct mq_attr *attr);int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,struct mq_attr *oldattr);

参数:

newattr:需要设置的属性

oldattr:原来的属性

//struct mq_attr结构体说明struct mq_attr{long mq_flags;/* Flags: 0 or O_NONBLOCK */long mq_maxmsg;/* Max. # of messages on queue: 消息队列能够保存的消息数 */long mq_msgsize;/* Max. message size (bytes): 消息的最大长度 */long mq_curmsgs;/* # of messages currently in queue: 消息队列当前保存的消息数 */};

/**SystemV消息队列

通过msgctl函数,并将cmd指定为IPC_STAT/IPC_SET来实现

intmsgctl(intmsqid,intcmd,structmsqid_ds*buf);

**/

/** 示例: 获取消息队列的属性**/int main(int argc,char **argv){mqd_t mqid = mq_open("/test", O_RDONLY|O_CREAT, 0666, NULL);if (mqid == -1)err_exit("mq_open error");struct mq_attr attr;if (mq_getattr(mqid, &attr) == -1)err_exit("mq_getattr error");cout << "Max messages on queue: " << attr.mq_maxmsg << endl;cout << "Max message size: " << attr.mq_msgsize << endl;cout << "current messages: " << attr.mq_curmsgs << endl;mq_close(mqid);return 0;}

5.发送消息

int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned msg_prio);

参数:

msg_ptr:指向需要发送的消息的指针

msg_len:消息长度

msg_prio:消息的优先级

/**SystemV消息队列

通过msgsnd函数来实现消息发送

intmsgsnd(intmsqid,constvoid*msgp,size_tmsgsz,intmsgflg);

**/

/** 示例: 向消息队列中发送消息, prio需要从命令行参数中读取 **/struct Student{char name[36];int age;};int main(int argc,char **argv){if (argc != 2)err_quit("./send <prio>");mqd_t mqid = mq_open("/test", O_WRONLY|O_CREAT, 0666, NULL);if (mqid == -1)err_exit("mq_open error");struct Student stu = {"xiaofang", 23};unsigned prio = atoi(argv[1]);if (mq_send(mqid, (const char *)&stu, sizeof(stu), prio) == -1)err_exit("mq_send error");mq_close(mqid);return 0;}

6.从消息队列中读取消息

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,size_t msg_len, unsigned *msg_prio);

参数:

msg_len:读取的消息的长度,注意:此值一定要等于mq_attr::mq_msgsize的值,该值可以通过mq_getattr获取,但一般是8192字节 [thismustbegreaterthanthemq_msgsizeattributeofthequeue(seemq_getattr(3)).]

msg_prio:保存获取的消息的优先级

返回值:

成功:返回读取的消息的字节数

失败:返回-1

注意:读取的永远是消息队列中优先级最高的最早的消息,如果消息队列为,如果不指定为非阻塞模式,则mq_receive会阻塞;

/**SystemV消息队列

通过msgrcv函数来实现消息发送的

ssize_tmsgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsgflg);

将会错过更好的风景,保持一份平和,保持一份清醒。

Linux IPC实践(7)

相关文章:

你感兴趣的文章:

标签云: