浅析libev的ev_signal过程
ev_signal是libev提供的对信号处理的一个模块,基本上是对sigaction函数的一个封装,并将本身是异步的信号转化为同步。ev_signal的使用十分简单:
#include <ev.h>
#include <stdio.h> static void
sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)
{
puts ( "signal ....." );
} int main(int argc,char* argv[])
{
struct ev_loop *loop = EV_DEFAULT; ev_signal signal_watcher;
ev_signal_init (&signal_watcher, sigint_cb, SIGINT);
ev_signal_start (loop, &signal_watcher); ev_run (loop,); return ;
}
C++的用法:
#include <iostream> #include <ev++.h>
#include <signal.h> class CSignal
{
public:
void sig_cb( ev::sig &w, int revents )
{
std::cout << "catch signal ..." << std::endl;
}
}; int main()
{
CSignal sg; ev::sig sig_watcher;
sig_watcher.set<CSignal,&CSignal::sig_cb>( &sg ); sig_watcher.start(SIGINT); ev_run( EV_DEFAULT, );
}
然后我们来看一下libev内部处理信号的大概流程:
1.libev有各种各样的watch,包括io、signal、timer,但这些watch基本使用以下结构
typedef struct ev_watcher {
int active;
int pending;
int priority;
void *data;
void (*cb)(struct ev_loop *loop, struct ev_watcher *w, int revents);
} ev_watcher;
2.libev定义了一个全局变量EV_DEFAULT,通过ev_default_loop (0)返回一个指针。其实ev_default_loop是在维护一个全局变量static struct ev_loop default_loop_struct当第一次调用ev_default_loop会初始化default_loop_struct,以后都只是返回它的指针了。这个全局变量自己在维护了所有的watcher。并在一个loop中检测它们是否触发事件。
3.当创建一个ev::sig对象,就创建了一个ev_watcher对象,并通过set函数设置对象指针,回调函数到对象里的data、cb变量,C方式则是通过ev_signal_init、ev_signal_set这些函数来设置。然后把这个watcher交给EV_DEFAULT管理。
4.当调用ev_signal_start函数,会调用signalfd为当前信号创建一个文件描述符,然后通过ev_io来监控该文件的读事件。如果signalfd失败,调用evpipe_init创建一个pipe,注册一个ev_io到epoll中。调用原生的sigaction函数,将回调函数处理为ev_sighandler,收到信号时在ev_sighandler中调用ev_feed_signal来往pipe中写数据。这样在一个loop中,原先的ev_watcher对象就会收到读消息。
可见,对于大多数使用了libev作为eventloop的程序而言,这样应该是足够简洁方便的。更重要的是,libev有一层C++的wrap,使得在使用C++构建的程序能更方便的调用类的成员函数,而原生的sigaction是不能注册类成员函数为回调函数的。但相对原生的sigaction而言,libev有一个致命的地方:必须要在事件循环中才能收到信号,即ev_run之后。想想,比如你的程序在初始化进入loop之前的时候当掉了,如果这时你想通过捕捉信号来做一些清理工作,libev办不到,sigaction则OK。
浅析libev的ev_signal过程的更多相关文章
- 浅析I/O处理过程与存储性能的关系
浅析I/O处理过程与存储性能的关系 https://community.emc.com/docs/DOC-28653 性能”这个词可以说伴随着整个IT行业的发展,每次新的技术出现,从硬件到软件大多数情 ...
- Bytom侧链Vapor源码浅析-节点出块过程
Bytom侧链Vapor源码浅析-节点出块过程 在这篇文章中,作者将从Vapor节点的创建开始,进而拓展讲解Vapor节点出块过程中所涉及的源码. 做为Vapor源码解析系列的第一篇,本文首先对Vap ...
- Linux入门——开机启动过程浅析
Linux开机启动过程浅析 Introduction 开机启动过程分为以下6个步骤,分别是BIOS, MBR, GRUB, Kernel, Init, RunLevel, RunDefinition ...
- 使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作. 有许多解决方案,但事件驱动也被广泛应用到网络编程中.并大规模部署在高 ...
- ibevent 和 libev 提高网络应用性能【转】
转自:https://www.cnblogs.com/kunhu/p/3632285.html 构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接, ...
- libevent 和 libev 提高网络应用性能
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作.有许多解决方 案,但是 libevent 库和 libev 库能够大大 ...
- 使用 libevent 和 libev 提高网络应用性能
使用 libevent 和 libev 提高网络应用性能 Martin C. Brown, 作家, Freelance 简介: 构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件, ...
- ffmpeg转码步骤源码实现的一点点浅析
ffmpeg转码实现的一点点浅析 ffmpeg转码过程对解码的处理封装在process_input()中(process_input()->decode_video()->decode() ...
- YII 的源码分析(-)
做为源码分析的首秀,我就挑了yii(读作歪依依而不是歪爱爱):它的赞美之词我就不多说了,直接入正题.先准备材料,建议直从官网下载yii的源码包(1.1.15). 在demos里边有一个最简单的应用—h ...
随机推荐
- 与Jquery Mobile的第一次亲密接触
Jquery Mobile闻名已久,今天终于有亲密接触的机会. 通过动手写的demo,对它有了一个基本的认识: 自带的UI组件用起来简洁,方便:对旧版本的浏览器或移动设备能做到很好的优雅降级,而不影响 ...
- 【转】WCF、WebAPI、WCFREST、WebService之间的区别
在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Services.我分享一下我对 ...
- [Redux] Extracting Presentational Components -- AddTodo
The code to be refactored: let nextTodoId = 0; class TodoApp extends Component { render() { const { ...
- compass模块----Utilities
引入Utilities: @import "compass/utilities"; 分别引入: @import "compass/utilities/color" ...
- 用web技术开发出原生的App应用的体会(1)
本人是是个前端小白,学前端已经有半年的时间了,前几天开了个博客,希望记录自己学习历程的点滴. 今天要写的是关于用html,css,javascript等web技术开发原生的app应用. 总所周知,we ...
- http status 源码
private static readonly String[][] s_HTTPStatusDescriptions = new String[][] { null, new String[] { ...
- arc engine - IName
IName对象是一个代表性对象.通过使用IName对象,可以访问它所代表的对象的一些基本属性,而不用将整个对象调入内存.我们用IWorkspace 获得一个Workspace,那可是会调入内存的,而I ...
- .net简单页面后台绑定下拉框,按钮,分页 前台aspx页面
一.aspx页面 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Updat ...
- c# 中的线程和同步
一.新建线程的3种方法 a)异步委托:b)Thread类:c)线程池: 二.异步委托 1.简单使用,检查委托是否完成其任务 a) 通过 BeginInvoke() 的返回值IAsyncResult ...
- D3.js data() 方法详解
Binding data(数据绑定) D3各种图表的作用体现在将数据(Data)转换成可视化的过程. 比如将一个月的气温数据,通过树形图来展现,能够直观的看到气温走势,下个月还需不需要穿秋裤 :) 我 ...