sigevent简介

首先给出官方文档地址:http://man7.org/linux/man-pages/man7/sigevent.7.html

首先,要明确sigevent的作用。sigevent只是一个结构体,而结构体本质上是用于存储数据信息的。由此,我们认为,sigevent的作用是为Linux/Unix系统调用函数API提供一个调用接口的通用参数;这类API的作用以某种特定的方式来通知进程到达的事件。API根据sigevent提供的结构,来具体处理有关信息。

下面给出sigevent的具体结构:

#include <signal.h>union sigval {          /* Data passed with notification */int  sival_int;         /* Integer value */void   *sival_ptr;      /* Pointer value */
};struct sigevent {int sigev_notify; /* Notification method */int sigev_signo;  /* Notification signal */union sigval sigev_value;  /* Data passed with notification */void (*sigev_notify_function) (union sigval);/* Function used for thread notification (SIGEV_THREAD) */void *sigev_notify_attributes;/* Attributes for notification thread (SIGEV_THREAD) */pid_t sigev_notify_thread_id; /* ID of thread to signal (SIGEV_THREAD_ID) */
};

每个参数的作用已经在英文的注释中说明了,不在赘述。下面主要说一下sigev_notify参数。该参数几个取值和作用如下:

  • SIGEV_NONE:空的提醒,事件发生时不做任何事情
  • SIGEV_SIGNAL:向进程发送sigev_signo中指定的信号,具体详细的状况参照上面的文档,这涉及到sigaction的使用
  • SIGEV_THREAD:通知进程在一个新的线程中启动sigev_notify_function函数,函数的实参是sigev_value,系统API自动启动一个线程,我们不用显式启动。

综上可知,sigevent结构体实际上是为各类系统调用API提供了一个统一的处理结构,我们只需要对提供sigevent结构的API,提供一个具体赋值结构体参数即可。下面通过mq_notify来实际说明该问题

mq_notify()简介

在这篇笔记中介绍了Posix消息队列的一般操作。

先给出该函数的接口

#include <mqueue.h>
int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
  • mqdes:消息队列的标识符
  • sevp:实际调用的参数,参数的意义参照sigevent结构体,或者直接看官方文档.

说明函数的作用:如果有新消息到达一个空的队列,允许调用线程注册一个异步通知,该通知会在消息到达时触发。核心的思想在异步这两个字上,也就是说,我们希望从消息队列中获取消息,但是不想让当前进程阻塞在一个空的消息队列上,那么通过该函数可以注册异步通知,来处理将来到达的事件。

几个注意事项:

  • 一个消息队列只能注册一个处理process
  • 如果当前进程想要移除注册的事件,只需要把sevp设置为NULL即可
  • 如果已经存在一个注册的事件进程,那么其他注册进程不会收到信号
  • 只有空消息队列在接收到第一个消息是,才会触发通知

代码实例

主进程创建一个消息队列,并注册一个事件,然后睡眠2秒模拟将来消息到达。之后主进程阻塞,模拟处理其他事件,在子进程中进行数据读取和程序退出。

#include <pthread.h>
#include <mqueue.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <signal.h>
#include <cstring>const char *mq_name = "/mq_test";inline void handle_error(const char *msg) {perror(msg);exit(EXIT_FAILURE);
}static void tfunc(union sigval sv) {struct mq_attr attr;ssize_t nr;void *buf;mqd_t mqdes = *((mqd_t *) sv.sival_ptr);if (mq_getattr(mqdes, &attr) == -1) {handle_error("mq_getattr() error\n");}buf = malloc(attr.mq_msgsize);if (buf == nullptr) {handle_error("malloc() error\n");}nr = mq_receive(mqdes, (char *) buf, attr.mq_msgsize, nullptr);if (nr == -1) {handle_error("mq_receive() error\n");}printf("Read %zd bytes from MQ\n", nr);free(buf);exit(EXIT_SUCCESS);
}int main() {mqd_t mqdes = mq_open(mq_name, O_CREAT | O_RDWR, 0777, nullptr);if (mqdes < (mqd_t) 0) {handle_error("mq_open() error\n");}struct sigevent sev;bzero(&sev, sizeof(sev));sev.sigev_notify = SIGEV_THREAD;sev.sigev_notify_function = tfunc;sev.sigev_notify_attributes = nullptr;sev.sigev_value.sival_ptr = &mqdes;  // 传递给tfunc的参数if (mq_notify(mqdes, &sev) == -1) {handle_error("mq_notify() error\n");}puts("sleep for 2 second...");sleep(2);const char *msg = "hello world!";mq_send(mqdes, msg, strlen(msg), 1);pause();exit(EXIT_SUCCESS);
}

Linux的sigevent结构----mq_notify()实例相关推荐

  1. linux下TCP通信简单实例

    linux下TCP通信简单实例 基于TCP(面向连接)的socket编程,分为服务器端和客户端 服务器端的流程如下: (1)创建套接字(socket) (2)将套接字绑定到一个本地地址和端口上(bin ...

  2. (第五篇)Linux操作系统基本结构介绍

    Linux操作系统基本结构介绍 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用 ...

  3. linux源码gpio模拟i2c,linux内核gpio模拟i2c实例.doc

    linux内核gpio模拟i2c实例.doc linux内核GPIO模拟I2C实例2010-10-11作者:cvip302814来源:cvip302814的blog前言:在许多情况下,我们并没有足够的 ...

  4. 【DG】在Linux平台上搭建单实例的dataguard--duplicate

    [DG]在Linux平台上搭建单实例的dataguard--duplicate 一 : 实验环境介绍 *** 鉴于生产环境均采用 64 位系统和数据库软件,本实验也将采用这个标准 *** 采用vmwa ...

  5. linux中c语言结构体详解,Linux C语言结构体-学习笔记

    Linux C语言结构体简介 前面学习了c语言的基本语法特性,本节进行更深入的学习. 预处理程序. 编译指令: 预处理, 宏定义, 建立自己的数据类型:结构体,联合体,动态数据结构 c语言表达式工具 ...

  6. 大数据技术之_01_Linux学习_01_linux的入门+VM和linux的安装+linux的目录结构+远程登录到linux服务器+vi和vim编辑器+开机、重启和用户登录注销+用户管理+用户组管理

    大数据学习之_01_Linux学习_01 1 linux的入门 1.1 Linux的介绍 2 VM和linux的安装 2.1 安装vm和Centos 2.1.1 基本说明 2.1.2 CentOS安装 ...

  7. linux IIC子系统分析(九)——实例分析通过设备节点访问I2c设备

    在< linux IIC子系统分析(四)--I2c bus初始化> 中我们创建了I2C 总线驱动,I2C adapter device 和adapter drivers也在这时创建 在&l ...

  8. 嵌入式linux结构框图,嵌入式linux系统的结构

    原标题:嵌入式linux系统的结构 1.嵌入式系统的硬件架构 嵌入式系统硬件模型结构,此系统主要由微处理器MPU.外围电路,以及外设组成,微处理器为ARM嵌入式处理芯片,如ARM7TMDI系列及ARM ...

  9. linux 中 timeval结构体 - Neddy11 - 博客园

    linux 中 timeval结构体 - Neddy11 - 博客园 linux 中 timeval结构体 网上很多人写到,timeval结构解释错误 ************************ ...

最新文章

  1. 正则表达式、事件调用
  2. 北京大学万小军教授:让机器进行文学创作,有什么进展和挑战?
  3. ((void *) 0)的含义和void的一些细节
  4. boost::mp11::mp_apply_q相关用法的测试程序
  5. Java 扫描并加载包路径下class文件
  6. XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager,
  7. jacobi matlab程序,jacobi迭代法实验MATLAB程序数值分析
  8. di-tech2016_2016年Tech最佳愚人节笑话
  9. html实现颜色色板,JS实现的系统调色板完整实例
  10. mappedBy reference an unknown target entity property错误
  11. 时钟系统安装配置注意事项
  12. JavaScript:用JS函数隐藏浏览器地址栏 .
  13. 用matlab解超越方程,MATLAB实例之对线性,非线性,超越方程的求解
  14. SpringBoot拦截器或过滤器中使用流读取参数后,controller中注解读取不到参数
  15. Python3.9标准库math中的函数汇总介绍(53个函数和5个常数)
  16. 随便写的一篇,记录我的hyperledger -ca折腾
  17. 美妆品牌如何做好营销推广?做好美妆行业品牌营销的方案有哪些?
  18. 浅谈用友NC产品单点登录机制
  19. SQL*Net message to client
  20. Redis系列教材 (四)- Jedis 教程

热门文章

  1. ubuntu 16.04 官网版安装 caffe 步骤详解[CPU][紧跟官网,永不踩坑]
  2. [转]你可能不知道的五个强大HTML5 API
  3. java中基本数据类型
  4. 敏捷开发绩效管理之七:敏捷开发生产率(下)(简化功能点分析,NESMA,两级简化)...
  5. 【编程珠玑】第四章 编写正确的程序
  6. 怎样不重启设置字体边缘平滑立即生效! 以下注册表导入后不能立即生效。。...
  7. spring整合mybatis的坑
  8. python数据类型—字符串
  9. win10 uwp 如何判断一个对象被移除
  10. 验证 decimal 和 数字