mqflag = 0;
ssize_t n;
mq_notify(mqid, &sigev); // 重新注册
while( (n = mq_receive(mqid,buff,attr.mq_msgsize,NULL)) >=0)
printf("SIGUSR1 received, read %ld bytes.\n",(long)n); //读取消息
if(errno != EAGAIN)
printf("mq_receive error\n");
sigprocmask(SIG_UNBLOCK,&newmask,NULL);
}
return 0;
}
void sig_usr1(int signo)
{
mqflag = 1;
}
��里为什么使用的是非阻塞式mq_receive,为什么不在信号处理程序中打印接收到的字符请参阅《unp 第二卷》
5.2 mq_notify() 使用线程处理程序
异步事件通知的另一种方式是把sigev_notify设置成SIGEV_THREAD,这会创建一个新线程,该线程调用由sigev_notify_function指定的函数,所用的参数由sigev_value指定,新线程的属性由sigev_notify_attributes指定,要指定线程的默认属性的话,传空指针。新线程是作为脱离线程创建的。
#include <unistd.h>
#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
mqd_t mqid = 0;
struct mq_attr attr;
struct sigevent sigev;
static void notify_thread(union sigval);
int main(int argc, char* argv[])
{
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
mqid = mq_open("/mq_test",O_RDONLY | O_NONBLOCK,mode,NULL);
mq_getattr(mqid,&attr);
sigev.sigev_notify = SIGEV_THREAD;
sigev.sigev_notify_function = notify_thread;
sigev.sigev_value.sival_ptr = NULL;
sigev.sigev_notify_attributes = NULL;
int n = mq_notify(mqid,&sigev);
for (;;)
pause();
return 0;
}
static void notify_thread(union sigval arg)
{
ssize_t n;
char* buff;
printf("notify_thread_started!\n");
buff = malloc(attr.mq_msgsize);
mq_notify(mqid, &sigev);
while( (n = mq_receive(mqid,buff,attr.mq_msgsize,NULL)) >=0)
printf("SIGUSR1 received, read %ld bytes.\n",(long)n);
if(errno != EAGAIN)
printf("mq_receive error\n");
free(buff);
pthread_exit(0);
}
一、进程间通信-管道 https://www.linuxidc.com/Linux/2018-04/151680.htm
二、进程间通信-命名管道 https://www.linuxidc.com/Linux/2018-04/151681.htm
三、进程间通信-消息队列 https://www.linuxidc.com/Linux/2018-04/151682.htm
四、进程间通信-共享内存 https://www.linuxidc.com/Linux/2018-04/151683.htm