<b>libevent源码浅析(三):libevent的信号的处理</b>[VC/C++编程]
本文“<b>libevent源码浅析(三):libevent的信号的处理</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
在libevent中通过利用socketpair成立一对流管道,也就是全双工管道,来将信号事件与句柄事件统一同来.
先来看数据构造:
struct evsignal_info {
struct event ev_signal; ///<所属的event
int ev_signal_pair[2]; ///<成立的流管道
int ev_signal_added; ///<信号能否已被加入到event中的标志.
volatile sig_atomic_t evsignal_caught; ///<事件触发标志,1表示有信号被触发
struct event_list evsigevents[NSIG]; ///<多个事件有大概注册到同一个信号,因此这里每个信号的事件都是一个event_list.
sig_atomic_t evsigcaught[NSIG]; ///<由于一个信号大概被注册多次,这里保存信号被捕捉的次数
#ifdef HAVE_SIGACTION
struct sigaction **sh_old;
#else
ev_sighandler_t **sh_old;
#endif
int sh_old_max;
};
接下来可以看几个主要的函数:
evsignal_init函数主要用来初始化一些数据构造.
void
evsignal_init(struct event_base *base)
{
int i;
///成立一对流管道
if (evutil_socketpair(
AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
event_err(1, "%s: socketpair", __func__);
///设置fd
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
///初始化sig数据构造
base->sig.sh_old = NULL;
base->sig.sh_old_max = 0;
base->sig.evsignal_caught = 0;
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
/* initialize the queues for all events */
///在libevent里面,全部的事件行列都用tail queue实现,linux下它利用的是linux自带的taile queue,具体用法可以去看man手册.
for (i = 0; i < NSIG; ++i)
TAILQ_INIT(&base->sig.evsigevents[i]);
///设置非阻塞
evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]);
///初始化event构造
event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1],
EV_READ | EV_PERSIST, evsignal_cb, &base->sig.ev_signal);
base->sig.ev_signal.ev_base = base;
base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
}
以上是“<b>libevent源码浅析(三):libevent的信号的处理</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |