突然想到Nginx中时间更新这块处理,Nginx中为了减少调用系统调用gettimeofday这个函数(因为一旦调用了系统调用,就会使得进程从用户态切换到内核态,就会发生上下文切换,这个代价很大且不值得)而设置了系统时间更新的次数,内部时间更新有两种方式,一种就是在配置文件中设置更新的评论,另一种是没有设置更新频率,在后面这种情况下,可以使用epoll_wait()这个函数的最后一个参数来控制反复的时间间隔,在Nginx内部使用了红黑树来管理定时事件,每次从堆顶选择一个最近的定时事件最为epoll_wait函数的最后一个参数。但是第一种方式是如何处理,系统内部设定了一个定时器,定时事件的时间间隔就是系统配置文件中用户自己设定的事件间隔,每次到一定的时间间隔后,都会有一个定时时间发生,如果epoll_wait处于睡眠状态,那么此进程就会被唤醒。这么一说,一个进程如果处于睡眠状态,那么用户也是可以使用别的方式来唤醒一个睡眠中的进程了!
我们再来回想一下前面有篇介绍EAGAIN和EINTER这两个错误的文章,EINTER这个错误时慢系统调用而触发的,如果慢系统调用睡眠了,这个时候有信号到达了,睡眠的进程被唤醒了,然后习惯性的查看信号队列,然后进程了用户的信号处理函数。这是正常的处理逻辑。所以在Nginx中使用一个定时器来更新时间是可靠的(定时器中的信号处理函数就是更新时间的。)
接下来我们看一下内核是如何处理进程的睡眠和唤醒的。
休眠(被阻塞)的进程处于一个特殊的不可执行状态。进程休眠由多种原因,但肯定都是为了等待一些事件。事件可能是一段时间从文件I/O读取更多数据