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;
}
posted @ 2025-05-29 11:40  站着说话不腰疼  阅读(42)  评论(0)    收藏  举报