POSIX消息队列
- 使用
man mq_overview
命令查看POSIX消息队列编程手册 - 头文件:
include<mqueue.h>
- 从消息队列中取出的是优先级最高且最先进入消息队列的消息
接收消息
#include <fcntl.h>
#include <mqueue.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define MQ_NAME "/my_mq"
struct msg_t {
int32_t data;
};
int main()
{
int len = sizeof(struct msg_t);
struct mq_attr attr = {
.mq_maxmsg = 10,
.mq_msgsize = len,
};
mqd_t mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
if (mq_fd == -1)
{
printf("mq_open failed: %s\n", strerror(errno));
return 0;
}
struct msg_t msg;
unsigned int prio;
long ret = mq_receive(mq_fd, (char*)&msg,len, &prio);
if (ret == -1)
{
printf("mq_send: %s\n", strerror(errno));
}
printf("mq received %ld bytes\n", ret);
printf("%d %d\n",msg.data, prio);
mq_close(mq_fd);
mq_unlink(MQ_NAME);
return 0;
}
监听消息
- 消息通知触发的条件:消息队列为空,且有新消息到达时
- 监听消息队列注册后只能触发1次,触发后需要重新注册
- 同时只能有一个进程注册消息队列监听
#include <fcntl.h>
#include <mqueue.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#define MQ_NAME "/my_mq"
struct msg_t {
int32_t data;
};
static void handle_mq_msg(union sigval sv)
{
mqd_t mq_fd = *((mqd_t*) sv.sival_ptr);
struct msg_t msg;
unsigned int prio;
int ret = mq_receive(mq_fd, (char*)&msg,sizeof(struct msg_t), &prio);
if (ret == -1)
{
printf("mq_receive failed: %s\n", strerror(errno));
}
printf("mq received %ld bytes\n", ret);
printf("%d %d\n",msg.data, prio);
ret = mq_notify(mq_fd, &sev);
if (ret == -1)
{
printf("mq_notify failed: %s\n", strerror(errno));
}
}
int main()
{
int len = sizeof(struct msg_t);
struct mq_attr attr = {
.mq_maxmsg = 10,
.mq_msgsize = len,
};
mqd_t mq_fd = mq_open(MQ_NAME,O_CREAT | O_RDONLY, 0666, &attr);
if (mq_fd == -1)
{
printf("mq_open failed: %s\n", strerror(errno));
return 0;
}
struct sigevent sev = {
.sigev_notify = SIGEV_THREAD,
.sigev_notify_function = handle_mq_msg,
.sigev_notify_attributes = NULL,
.sigev_value.sival_ptr = &mq_fd,
};
int ret = mq_notify(mq_fd, &sev);
if (ret == -1)
{
printf("mq_notify failed: %s\n", strerror(errno));
}
pause();
mq_close(mq_fd);
mq_unlink(MQ_NAME);
return 0;
}
发送消息
#include <fcntl.h>
#include <mqueue.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define MQ_NAME "/my_mq"
struct msg_t {
int32_t data;
};
int main()
{
mqd_t mq_fd = mq_open(MQ_NAME,O_WRONLY);
if (mq_fd == -1)
{
printf("mq_open failed: %s\n", strerror(errno));
return 0;
}
struct msg_t msg = {8888};
long ret = mq_send(mq_fd, (char*)&msg, sizeof(struct msg_t), 1);
if (ret == -1)
{
printf("mq_send: %s\n", strerror(errno));
return 0;
}
printf("mq send successfully\n");
mq_close(mq_fd);
return 0;
}
System V消息队列