17.posix消息队列
posix消息队列
如果没有安装依赖(Debian/ubuntu)
sudo apt-get update
sudo apt-get install manpages-posix-dev
测试:
man mq_send
1.编写一个发送接收消息案例:
mqTest.c
#include <mqueue.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#if 0
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 *ptr, size_tlen, unsigned int prio);
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_tlen, unsigned int *prio);
int mq_notify(mqd_t mqdes, const struct sigevent
*notification);
#endif
#define QUEUE_NAME "/test_queue"
#define MESSAGE "mqueue,test"
void *sender_thread(void *argv)
{
//发送消息
mqd_t mqd = *(mqd_t *)argv;
int ret = -1;
char message[] = MESSAGE;
printf("sender_thread start\n");
sleep(10);
ret = mq_send(mqd, message, strlen(message)+1, 0);
printf("sender_thread send message:%s,mqd_t:%d\n",message,mqd);
if(-1 == ret){
if(errno == EAGAIN){
printf("Message queue is full\n");
}else{
perror("Message send error");
}
}
return NULL;
}
void *receiver_thread(void *argv)
{
//接收消息
mqd_t mqd = *(mqd_t *)argv;
char buffer[256];
int size = -1;
printf("receiver_thread start\n");
sleep(20);
size = mq_receive(mqd, buffer, 256, 0);
if(size == 1){
perror("Message recevie error");
}
sleep(10);
printf("Message receive:%s,size:%d\n",buffer,size);
return NULL;
}
int main(int argc,char *argv[])
{
//创建线程
pthread_t sender,receiver;
//创建消息队列
mqd_t mqd = -1;
struct mq_attr attr;
attr.mq_flags = 0;//阻塞标志, 0(阻塞)或O_NONBLOCK
attr.mq_maxmsg = 10;//最大消息数
attr.mq_msgsize = 256; //每个消息最大大小
attr.mq_curmsgs = 0;//当前消息数
mqd = mq_open(QUEUE_NAME, O_RDWR|O_CREAT, 0644, &attr);
if(mqd == -1){
perror("mq_open");
return -1;
}
if(pthread_create(&sender,NULL,sender_thread,(void *)&mqd) != 0){
perror("pthread_create receiver error");
return -1;
}
if(pthread_create(&receiver,NULL,receiver_thread,(void *)&mqd) != 0){
perror("pthread_create receiver error");
return -1;
}
pthread_join(sender,NULL);
pthread_join(receiver,NULL);
mq_close(mqd);
mq_unlink(QUEUE_NAME);
return 0;
}
2.异步通知:
mqNotifyTest.c
#include <mqueue.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h> // 定义 SIGEV_THREAD 和其他信号相关常量
#if 0
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 *ptr, size_tlen, unsigned int prio);
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_tlen, unsigned int *prio);
int mq_notify(mqd_t mqdes, const struct sigevent
*notification);
#endif
#define QUEUE_NAME "/test_queue"
#define MESSAGE "mqueue,notifymes"
void *sender_thread(void *argv)
{
//发送消息
mqd_t mqd = *(mqd_t *)argv;
int ret = -1;
char message[] = MESSAGE;
printf("sender_thread start\n");
sleep(5);
ret = mq_send(mqd, message, strlen(message)+1, 0);
printf("sender_thread send message:%s,mqd_t:%d\n",message,mqd);
if(-1 == ret){
if(errno == EAGAIN){
printf("Message queue is full\n");
}else{
perror("Message send error");
}
}
return NULL;
}
void notify_thread(union sigval sv)
{
//接收消息
printf("notify rev data 1\n");
mqd_t mqd = -1;
mqd = *(mqd_t *)sv.sival_ptr;
char buffer[256];
int rev_size = -1;
printf("notify rev data start\n");
rev_size = mq_receive(mqd, buffer, sizeof(buffer), NULL);
if(-1 == rev_size){
perror("notify rev error");
}
struct sigevent sev;
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = notify_thread;
sev.sigev_value.sival_ptr = &mqd; /* Arg. to thread func. */
if (mq_notify(mqd, &sev) == -1){
perror("mq_notify");
exit(1);
}
printf("receive message :%s,size:%d\n",buffer,rev_size);
}
int main(int argc,char *argv[])
{
//创建线程
pthread_t sender,receiver;
//创建消息队列
mqd_t mqd = -1;
struct mq_attr attr;
attr.mq_flags = 0;//阻塞标志, 0(阻塞)或O_NONBLOCK
attr.mq_maxmsg = 10;//最大消息数
attr.mq_msgsize = 256; //每个消息最大大小
attr.mq_curmsgs = 0;//当前消息数
mqd = mq_open(QUEUE_NAME, O_RDWR|O_CREAT, 0644, &attr);
if(mqd == -1){
perror("mq_open");
return -1;
}
printf("sigevent create\n");
struct sigevent sev;
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = notify_thread;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &mqd; /* Arg. to thread func. */
printf("sigevent mq_notify\n");
if (mq_notify(mqd, &sev) == -1){
perror("mq_notify");
exit(1);
}
printf("sigevent end\n");
if(pthread_create(&sender,NULL,sender_thread,(void *)&mqd) != 0){
perror("pthread_create sender error");
return -1;
}
pthread_join(sender,NULL);
sleep(5);
mq_close(mqd);
mq_unlink(QUEUE_NAME);
return 0;
}

浙公网安备 33010602011771号