UNIX IPC: POSIX 消息队列

首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边。在Ubuntu上使用正常,不过POSIX消息队列通过ipcs命令是看不到的,需要通过如下方式进行查看:

mount -t mqueue none /mnt
ls -al /mnt

ls列出的文件即为程序中创建的POSIX消息队列,消息队列的名称需要以“/”开头否则会提示参数非法。通过cat查看这个文件可以知道这个队列的一些参数如:

hgf@ubuntu:~/ipc$ cat /mnt/testmq

QSIZE: NOTIFY: SIGNO: NOTIFY_PID:

编译代码时需要加上-lrt参数,即连接Posix.1 realtime库,

基本操作API

mqd_t mq_open(const char* name, int oflag, ... /* mode_t mode, struct mq_attr attr */);

int mq_close(mqd_t mqdes);

int mq_unlink(const char* name);

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

int mq_setattr(mqd_t mqdes, struct mq_attr* attr, struct mq_attr* oattr);

int mq_send(mqd_t mqdes, const char* buf, size_t len, unsigned int prior);

int mq_receive(mqd_t mqdes, const char* buf, size_t len, unsigned int* priop);

mqcreate.c (gcc mqcreate.c -lrt -o mqcreate)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <unistd.h>
#include <getopt.h> struct mq_attr attr; int main(int argc, char** argv) {
char opt; char* MQ_NAME = "/testmq"; int OPEN_MODE = O_RDWR | O_CREAT;
int FILE_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; while((opt = getopt(argc, argv, "en:m:z:")) != -) {
switch(opt) {
case 'e':
OPEN_MODE |= O_EXCL;
break;
case 'm':
attr.mq_maxmsg = atol(optarg);
break;
case 'z':
attr.mq_msgsize = atol(optarg);
break;
case 'n':
MQ_NAME = optarg;
break;
}
} printf("msg queue name:%s\nmsg max size: %ld\nmsg per size: %ld\n",
MQ_NAME, attr.mq_maxmsg, attr.mq_msgsize); struct mq_attr* attrarg = NULL;
if (attr.mq_maxmsg != ) {
attrarg = &attr;
} mqd_t mq = mq_open(MQ_NAME, OPEN_MODE, FILE_MODE, attrarg); if (mq < ) {
perror("message queue create failed:");
return ;
} return ;
}

mqunlink.c (gcc mqunlink.c -lrt -o mqunlink)

#include <stdio.h>
#include <stdlib.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mqueue.h> int main(int argc, char** argv) {
char* MQ_NAME = "/testmq"; if (argc > ) {
MQ_NAME = argv[];
} int res = mq_unlink(MQ_NAME); if (res < ) {
perror("close message queue:");
} return ;
}

mqgetattr.c

#include <stdio.h>
#include <stdlib.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mqueue.h> int main(int argc, char** argv) {
char* name = "/testmq"; if (argc > ) {
name = argv[];
} mqd_t mq = mq_open(name, O_RDONLY); if (mq < ) {
perror("open message queue failed:");
return ;
} struct mq_attr attr; mq_getattr(mq, &attr); printf("max #msgs = %ld, max #bytes/msg = %ld, #current = %ld\n",
attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs
); int res = mq_close(mq); if (res != ) {
perror("close message queue failed:");
}
return ;
}

mqsend.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mqueue.h> int main(int argc, char** argv) {
mqd_t mqd;
void *ptr;
size_t len;
unsigned int prio; if (argc != ) {
printf("%s msg_queue_name message priority\n", argv[]);
return -;
} mqd = mq_open(argv[], O_WRONLY); if (mqd < ) {
perror("open message queue failed");
return -;
} len = strlen(argv[]) + ; ptr = malloc(len); prio= atoi(argv[]); strcpy(ptr, argv[]); int res = mq_send(mqd, ptr, len, prio); if (res != ) {
perror("send msg faild");
return -;
} return ;
}

mqreceive.c

#include <stdio.h>
#include <stdlib.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <getopt.h> int main(int argc, char** argv) { char opt; char* queue = "/testmq"; int FILE_MODE = O_RDONLY; while ((opt = getopt(argc, argv, "xn:")) != -) {
switch (opt) {
case 'n':
queue = optarg;
break;
case 'b':
FILE_MODE |= O_NONBLOCK;
break;
}
} mqd_t mqd = mq_open(queue, FILE_MODE); if (mqd < ) {
perror("open message queue failed");
return -;
} struct mq_attr attr;
char* buffer = NULL;
int prio; mq_getattr(mqd, &attr);
buffer = malloc(attr.mq_msgsize + ); for(;;) {
int res = mq_receive(mqd, buffer, attr.mq_msgsize, &prio);
if (res < ) {
perror("read msg fail");
return;
} printf("read msg size:%u, msg(%s), prio:%d\n", res, buffer, prio);
if (FILE_MODE & O_NONBLOCK) {
sleep();
printf(".");
}
}
return ;
}
上一篇:IPC通信:Posix消息队列


下一篇:Linux IPC实践(7) --Posix消息队列