天天看点

Libevent编程-捕获 signal参考资料

Libevent 是一个轻量级的开源高性能网络库,事件驱动(event-driven), 实现基于 Reactor 模式,网上学习资料众多,这里分享一下关于 signal 的处理。

首先给出 libevent 对 signal 的处理宏定义:

evsignal_* macros
   Aliases for working with signal events

  #define evsignal_add(ev,  tv)   event_add((ev), (tv))   
  #define evsignal_assign(ev, b, x, cb, arg) \            
          event_assign((ev), (b), (x), EV_SIGNAL|EV_PERSIST, cb, (arg))
  #define evsignal_new(b,  x,  cb,  arg)\
         event_new((b), (x), EV_SIGNAL|EV_PERSIST, (cb), (arg))
  #define evsignal_del(ev)   event_del(ev)
  #define evsignal_pending(ev,  tv)  event_pending((ev), EV_SIGNAL, (tv))
  #define evsignal_initialized(ev)   event_initialized(ev)
           

signal 事件的处理函数即是普通 event 事件的处理函数别无二致,唯一不同之处在于在文件描述符,signal 事件该参数的意义是 signal no,我们可以用 kill -l 命令查看系统的 signal table:

Libevent编程-捕获 signal参考资料

常用的信号 有SIGINT ( CTRL+C),SINPIPE(经常用于网络编程)。

我这里先写一个例子:

#include <stdio.h>
#include <stdlib.h>

#include <event2/event.h>
#include <event2/event_struct.h>

void handler(int signo, short events, void* arg) {
        printf("Receive signal %d\n", signo);
}

int main()
{

        struct event_base* base = event_base_new();
        int signo = SIGINT;
        struct event *sig_event = evsignal_new(base, signo, handler, NULL);
        evsignal_add(sig_event, NULL);
        event_base_dispatch(base);

        exit();
}
           

这里我以SIGINT信号为例,首先写一个信号处理函数

void handler(int signo, short events, void* arg)

该函数的形参与一般的回调函数无异,处理内容也很简单,就是打印出收到的 signal,当然真实情况需要做更适当的处理。

上面的代码处理很简单:

首先新建一个 event 变量用于处理信号

struct event * sig_event = evsignal_new(base, signo, handler, NULL);

接着将它注册到信号事件队列

evsignal_add(sig_event, NULL);

剩下的就和普通事件完全一样了。

编译:

gcc -o proc event-signal-demo.c -levent

运行测试:

Libevent编程-捕获 signal参考资料

按下 CTRL + C会发现程序不会像平常那般退出,而是打印出

“^CReceive signal 2”

程序捕捉到了 SIGINT 信号,over。

此外讨论一下,如何对特定的线程发出特定的信号,仍以上面的程序为例,除了采用CTRL + C产生 SIGINT 信号外,更一般的方法是借助 kill 命令。

首先先求得目的线程的 PID,利用如下命令:

ps aux | grep proc | grep -v grep

在结果中得出 proc 进程的 PID 为2719。接着使用

kill -2 2719

就可以向 proc 进程发送 SIGINT 信号了(这里的2是 SIGINT 的 signo)。

Libevent编程-捕获 signal参考资料

允许转载

参考资料

libevent源码深度剖析 张亮

Fast portable non-blocking network programming with Libevent (没发现作者是谁)

继续阅读