Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >libevent源码深度剖析八 集成信号处理

libevent源码深度剖析八 集成信号处理

作者头像
范蠡
发布于 2018-07-25 08:05:59
发布于 2018-07-25 08:05:59
85500
代码可运行
举报
运行总次数:0
代码可运行

系列目录

(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点

现在我们已经了解了libevent的基本框架:事件管理框架和事件主循环。上节提到了libevent中I/O事件和Signal以及Timer事件的集成,这一节将分析如何将Signal集成到事件主循环的框架中。

1.集成策略——使用socket pair

前一节已经做了足够多的介绍了,基本方法就是采用“消息机制”。在libevent中这是通过socket pair完成的,下面就来详细分析一下。 Socket pair就是一个socket对,包含两个socket,一个读socket,一个写socket。工作方式如下图所示:

创建一个socket pair并不是复杂的操作,可以参见下面的流程图,清晰起见,其中忽略了一些错误处理和检查。

Libevent提供了辅助函数evutil_socketpair()来创建一个socket pair,可以结合上面的创建流程来分析该函数。

2.集成到事件主循环——通知event_base

Socket pair创建好了,可是libevent的事件主循环还是不知道Signal是否发生了啊,看来我们还差了最后一步,那就是:为socket pair的读socket在libevent的event_base实例上注册一个persist的读事件。 这样当向写socket写入数据时,读socket就会得到通知,触发读事件,从而event_base就能相应的得到通知了。 前面提到过,Libevent会在事件主循环中检查标记,来确定是否有触发的signal,如果标记被设置就处理这些signal,这段代码在各个具体的I/O机制中,以Epoll为例,在epoll_dispatch()函数中,代码片段如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
 2    if (res == -1) {
 3        if (errno != EINTR) {
 4            event_warn("epoll_wait");
 5            return (-1);
 6        }
 7        evsignal_process(base);// 处理signal事件
 8        return (0);
 9    } else if (base->sig.evsignal_caught) {
10        evsignal_process(base);// 处理signal事件
11}

完整的处理框架如下所示:

注1:libevent中,初始化阶段并不注册读socket的读事件,而是在注册信号阶段才会测试并注册; 注2:libevent中,检查I/O事件是在各系统I/O机制的dispatch()函数中完成的,该dispatch()函数在event_base_loop()函数中被调用;

3.evsignal_info结构体

libevent中Signal事件的管理是通过结构体evsignal_info完成的,结构体位于evsignal.h文件中,定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1struct evsignal_info {
 2    struct event ev_signal;
 3    int ev_signal_pair[2];
 4    int ev_signal_added;
 5    volatile sig_atomic_t evsignal_caught;
 6    struct event_list evsigevents[NSIG];
 7    sig_atomic_t evsigcaught[NSIG];
 8#ifdef HAVE_SIGACTION
 9    struct sigaction **sh_old;
10#else
11    ev_sighandler_t **sh_old;
12#endif
13    int sh_old_max;
14};

下面详细介绍一下个字段的含义和作用: 1)ev_signal, 为socket pair的读socket向event_base注册读事件时使用的event结构体; 2)ev_signal_pair,socket pair对,作用见第一节的介绍; 3)ev_signal_added,记录ev_signal事件是否已经注册了; 4)evsignal_caught,是否有信号发生的标记;是volatile类型,因为它会在另外的线程中被修改; 5)evsigvents[NSIG],数组,evsigevents[signo]表示注册到信号signo的事件链表; 6)evsigcaught[NSIG],具体记录每个信号触发的次数,evsigcaught[signo]是记录信号signo被触发的次数; 7)sh_old记录了原来的signal处理函数指针,当信号signo注册的event被清空时,需要重新设置其处理函数; evsignal_info的初始化包括,创建socket pair,设置ev_signal事件(但并没有注册,而是等到有信号注册时才检查并注册),并将所有标记置零,初始化信号的注册事件链表指针等。

4.注册、注销signal事件

注册signal事件是通过evsignal_add(struct event *ev)函数完成的,libevent对所有的信号注册同一个处理函数evsignal_handler(),该函数将在下一段介绍,注册过程如下: 1 取得ev要注册到的信号signo; 2 如果信号signo未被注册,那么就为signo注册信号处理函数evsignal_handler(); 3 如果事件ev_signal还没哟注册,就注册ev_signal事件; 4 将事件ev添加到signo的event链表中; 从signo上注销一个已注册的signal事件就更简单了,直接从其已注册事件的链表中移除即可。如果事件链表已空,那么就恢复旧的处理函数; 下面的讲解都以signal()函数为例,sigaction()函数的处理和signal()相似。 处理函数evsignal_handler()函数做的事情很简单,就是记录信号的发生次数,并通知event_base有信号触发,需要处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1static void evsignal_handler(int sig){
 2    int save_errno = errno; // 不覆盖原来的错误代码
 3    if (evsignal_base == NULL) {
 4        event_warn("%s: received signal %d, but have no base configured", __func__, sig);
 5        return;
 6    }
 7    // 记录信号sig的触发次数,并设置event触发标记
 8    evsignal_base->sig.evsigcaught[sig]++;
 9    evsignal_base->sig.evsignal_caught = 1;
10#ifndef HAVE_SIGACTION
11    signal(sig, evsignal_handler); // 重新注册信号
12#endif
13    // 向写socket写一个字节数据,触发event_base的I/O事件,从而通知其有信号触发,需要处理
14    send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0);
15    errno = save_errno; // 错误代码
16}

5.小节 本节介绍了libevent对signal事件的具体处理框架,包括事件注册、删除和socket pair通知机制,以及是如何将Signal事件集成到事件主循环之中的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 高性能服务器开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
libevent源码深度剖析十三 libevent信号处理注意点
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
6730
libevent源码深度剖析十三 libevent信号处理注意点
libevent源码深度剖析(六) 初见事件处理框架
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
1.2K0
libevent源码深度剖析(五) libevent的核心:事件event
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
1.2K0
libevent源码深度剖析(五) libevent的核心:事件event
libevent介绍
libevent是一款事件驱动的网络开发包 由于采用 c 语言开发 体积小巧,跨平台,速度极快。
Java架构师必看
2021/03/22
2K0
libevent源码深度剖析七 事件主循环
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
9710
libevent源码深度剖析七 事件主循环
libevent源码深度剖析三 libevent基本使用场景和事件流程
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
2K1
libevent源码深度剖析三 libevent基本使用场景和事件流程
memcached源码阅读----使用libevent和多线程模型
本篇文章主要是我今天阅读memcached源码关于进程启动,在网络这块做了哪些事情。
ctree
2019/02/24
1.4K0
深入理解libevent事件库的原理与实践技巧
libevent是一个事件通知库;封装了reactor。 libevent API 提供了一种机制,用于在文件描述符上发生特定事件或达到超时后执行回调函数。此外,libevent还支持由于信号或常规超时而导致的回调。 libevent 旨在替换在事件驱动的网络服务器中找到的事件循环。应用程序只需要调用event_dispatch(),然后动态添加或删除事件,而无需更改事件循环。
Lion Long
2024/10/20
3260
深入理解libevent事件库的原理与实践技巧
使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史
http://blog.csdn.net/hguisu/article/details/38638183(牛逼100多名)
bear_fish
2018/09/20
2.1K0
使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史
libevent的事件机制
从上一篇文章《libevent是怎么选择底层实现的》可以看出来,调用event_base_new()函数就是初始化好底层实现,给event_base结构体中evsel赋值,evsel是一个eventop结构体,我们再来看下:
cpp加油站
2021/04/16
8220
libevent源码深度剖析二 Reactor模式
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
1.2K0
libevent源码深度剖析二 Reactor模式
libevent源码深度剖析九 集成定时器事件
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
1.4K0
libevent源码深度剖析九 集成定时器事件
libevent源码深度剖析十 支持I/O多路复用技术
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
7660
libevent源码深度剖析四 libevent源代码文件组织
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
9700
libevent源码深度剖析十一 时间管理
(1)libevent源码深度剖析一 序 (2)libevent源码深度剖析二 Reactor模式 (3)libevent源码深度剖析三 libevent基本使用场景和事件流程 (4)libevent源码深度剖析四 libevent源代码文件组织 (5)libevent源码深度剖析五 libevent的核心:事件event (6)libevent源码深度剖析六 初见事件处理框架 (7)libevent源码深度剖析七 事件主循环 (8)libevent源码深度剖析八 集成信号处理 (9)libevent源码深度剖析九 集成定时器事件 (10)libevent源码深度剖析十 支持I/O多路复用技术 (11)libevent源码深度剖析十一 时间管理 (12)libevent源码深度剖析十二 让libevent支持多线程 (13)libevent源码深度剖析十三 libevent信号处理注意点
范蠡
2018/07/25
7460
libuv源码解析之信号处理
经过一系列的操作后,主要是申请了一个用于互斥控制的管道,然后往管道里写数据。后面就可以使用lock和unlock进行加锁解锁。接着在第一个注册信号的时候,还会做一些初始化的工作。
theanarkh
2020/01/15
8910
linux下libevent的安装和使用例子:数据回显
http://blog.csdn.net/fall221/article/details/9045353 (安装)
bear_fish
2018/09/20
3.4K0
linux下libevent的安装和使用例子:数据回显
几种服务器端IO模型的简单介绍及实现(下)
5、使用事件驱动库libevent的服务器模型 Libevent 是一种高性能事件循环/事件驱动库。 为了实际处理每个请求,libevent 库提供一种事件机制,它作为底层网络后端的包装器。事件系统让为连接添加处理函数变得非常简便,同时降低了底层IO复杂性。这是 libevent 系统的核心。 创建 libevent 服务器的基本方法是,注册当发生某一操作(比如接受来自客户端的连接)时应该执行的函数,然后调用主事件循环 event_dispatch()。执行过程的控制现在由 libevent 系统处理。注册
李海彬
2018/03/23
6940
几种服务器端IO模型的简单介绍及实现(下)
Linux信号处理
目前 Linux 支持64种信号。信号分为非实时信号(不可靠信号)和实时信号(可靠信号)两种类型,对应于 Linux 的信号值为 1-31 和 34-64。
用户7686797
2020/08/25
5.9K0
libevent简单服务端和客户端实现
在开始使用之前,我们需要先搞清楚libevent编译生成的各个动态库的作用。 在下载libevent源码包进行编译以后,当前目录生成.libs目录,该目录下是所有的目标文件,这里我们只说明个动态库so文件的作用,通过makefile我们可以知道各个动态库包含内容:
cpp加油站
2021/04/16
2.2K0
推荐阅读
相关推荐
libevent源码深度剖析十三 libevent信号处理注意点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验