Web服务器的定时器
参考:
最新版Web服务器项目详解 - 07 定时器处理非活动连接(上)
最新版Web服务器项目详解 - 08 定时器处理非活动连接(下)
我的误区:
- sigaction结构体中的 sigset_t sa_mask
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}
sa_mask用来指定在信号处理函数执行期间需要被屏蔽的信号。只是指定处理期间需要屏蔽的而已。
- sigfillset函数
#include <signal.h>
int sigfillset(sigset_t *set);
用来将参数set信号集初始化,然后把所有的信号加入到此信号集里。
与sigaction结构体中的sa_mask联用,实现在处理信号时屏蔽其他所有信号。
-
socketpair函数
在linux下,使用socketpair函数能够创建一对套接字进行通信,项目中使用管道通信。 -
send函数
曾经我也很疑惑如何判断缓冲区可写。实际上缓冲区非满时理论上就可写?
当套接字发送缓冲区变满时,send通常会阻塞,除非套接字设置为非阻塞模式,当缓冲区变满时,返回EAGAIN或者EWOULDBLOCK错误,此时可以调用select(epoll EPOLLOUT?)函数来监视何时可以发送数据。 -
统一事件源
统一事件源,是指将信号事件与其他事件一样被处理。
也就是都放在主循环中,同其他信号事件一样被处理。 -
信号处理机制

接收信号的任务是由内核代理的,当内核接收到信号后,会将其放到对应进程的信号队列中,同时向进程发送一个中断,使其陷入内核态。注意,此时信号还只是在队列中,对进程来说暂时是不知道有信号到来的。
进程陷入内核态后,有两种场景会对信号进行检测:?
- 进程从内核态返回到用户态前进行信号检测
- 进程在内核态中,从睡眠状态被唤醒的时候进行信号检测
当发现有新信号时,便会进入下一步,信号的处理。
( 内核 )信号处理函数是运行在用户态的,调用处理函数前,内核会将当前内核栈的内容备份拷贝到用户栈上,并且修改指令寄存器(eip)将其指向信号处理函数。
( 用户 )接下来进程返回到用户态中,执行相应的信号处理函数。
( 内核 )信号处理函数执行完成后,还需要返回内核态,检查是否还有其它信号未处理。
( 用户 )如果所有信号都处理完成,就会将内核栈恢复(从用户栈的备份拷贝回来),同时恢复指令寄存器(eip)将其指向中断前的运行位置,最后回到用户态继续执行进程。
至此,一个完整的信号处理流程便结束了,如果同时有多个信号到达,上面的处理流程会在第2步和第3步骤间重复进行。

浙公网安备 33010602011771号