Posix消息队列异步通知功能

/*************************************************************************
    > File Name: test.c
    > Author: ndj
    > Mail: ndj_ydd@163.com 
    > Created Time: Tue 07 Nov 2017 03:39:34 PM CST
 ************************************************************************/
/*启动一个新线程的mq_notify*/
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<mqueue.h>
#include<pthread.h>
#include<signal.h>
#include<errno.h>
mqd_t mqd;
struct mq_attr attr;
struct sigevent sigev;

static void notify_thread(union sigval);

int main(int argc, char **argv)
{
    if(argc != 2)
    {
        fprintf(stderr, "argc != 2\n");
        exit(EXIT_FAILURE);
    }
    mqd = mq_open(argv[1], O_RDONLY | O_NONBLOCK);
    mq_getattr(mqd, &attr);

    sigev.sigev_notify = SIGEV_THREAD;
    sigev.sigev_value.sival_ptr = NULL;
    sigev.sigev_notify_function = notify_thread;
    sigev.sigev_notify_attributes = NULL;
    mq_notify(mqd, &sigev);

    for( ; ; )
        pause();
}

static void notify_thread(union sigval arg)
{
    ssize_t n;
    void *buffer;

    printf("notify_thread started\n");
    buffer = malloc(attr.mq_msgsize);
    mq_notify(mqd, &sigev);/*resister*/
    /*加入消息未读之前在来消息,不会产生新的线程读取,只有非阻塞打开,然后循环读取*/
    /*这里不会出现signal一样的现象(信号消失),在没有读取消息队列的消息之前不会创建新线程*/
    /*这里消息队列中在有新的数据添加进来,没有办法产生新的线程,所以要循环读取.因此为了产生结束标志要非阻塞打开*/
    while((n = mq_receive(mqd, buffer, attr.mq_msgsize, NULL)) >= 0)
        printf("read %ld bytes\n",(long)n);
    if(errno != EAGAIN)
        printf("mq_receive error\n");
    free(buffer);
    pthread_exit(0);
}
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<mqueue.h>
#include<signal.h>
#include<errno.h>
volatile sig_atomic_t mqflag;
static void sig_usr1(int);
/*使用非阻塞的mq_receive的信号通知*/
int main(int argc, char **argv)
{
    mqd_t mqd;
    void *buffer;
    size_t len;
    struct mq_attr attr;
    sigset_t newmask, oldmask, zeromask;
    struct sigevent sigev;
    ssize_t n;
    if(argc != 2)
    {
        fprintf(stderr, "argc != 2\n");
        exit(EXIT_FAILURE);
    }
    mqd = mq_open(argv[1], O_RDONLY | O_NONBLOCK);
    mq_getattr(mqd, &attr);
    buffer = malloc(attr.mq_msgsize);

    sigemptyset(&zeromask);/*no signal block*/
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGUSR1);

    /*establish signal handler, enable notification*/
    signal(SIGUSR1, sig_usr1);
    sigev.sigev_notify = SIGEV_SIGNAL;
    sigev.sigev_signo = SIGUSR1;
    printf("sleep 10ms\n");
    sleep(10);
    mq_notify(mqd, &sigev);

//  printf("sleep 10ms\n");
//  sleep(10);
    for( ; ; )
    {
        sigprocmask(SIG_BLOCK, &newmask, &oldmask);
        while(mqflag == 0)
            sigsuspend(&zeromask);
        mqflag = 0;
        mq_notify(mqd, &sigev);
        while((n = mq_receive(mqd, buffer, attr.mq_msgsize, NULL)) > 0)
            printf("read %ld bytes\n", (long)n);

        if(errno != EAGAIN)
            printf("mq_receive error\n");
        sigprocmask(SIG_UNBLOCK, &newmask, NULL);
    }
    exit(0);
}

static void sig_usr1(int signo)
{
    mqflag = 1;
    return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值