我正在读关于如何alarm()call 可在 Linux 上运行。
alarm(5)会发送一个SIGALRM至少 5 秒内到达发出此调用的进程。
由于内核设置的递减计数器达到零,此时会引起警报。
我的疑问在这里 - 我们可以有 N 个发出警报呼叫的进程,并且系统中有一个可用于此目的的递减计数器。因此,内核必须通过一个递减计数器来跟踪它必须向其发送信号的所有进程。它是如何做到的?
[它是否维护一个排序链表,每个节点代表一个过程?]
我不是 Linux 内核开发人员,但考虑到man-page for alarm()
,你已经可以预料到它是如何实现的了。
首先,很明显警报值是针对每个进程的。由于内核已经保留了每个进程的数据结构(task_struct),它只是将所需的闹钟时间存储在那里。然后Linux只是使用其内部定时器系统在指定时间注册回调。然后,所述回调将 SIGALRM 传递给您的进程。
警报不需要内核全局状态或链接的显式链表。内核只是保留一个进程列表并将警报超时存储为每个进程数据的一部分。
如果你想更深入地挖掘,调用树看起来像这样:
- 系统警报()
- Alarm_setTimer()
-
do_setitimer():这将内核计时器存储在 as 下
task_struct->signal->real_timer
;然后它传递调用
-
hrtimer_start(),它是 Linux 内部高分辨率计时器 API 的一部分。
进一步挖掘,Linux 高分辨率内核定时器系统可以做很多事情,例如区分实时(如果有人更改计算机上的时间/日期,可能会倒退)和单调时间。看一眼这篇 LWN 文章以获得概述。
出于此问题的目的,它在内部保留按到期时间排序的计时器列表(首先是即将到期的计时器,最后是稍后到期的计时器)。出于性能原因,这不是作为双向链表实现的,而是作为红黑树。处理完任何回调后,hrtimers 查看其列表,选择第一个条目(最快到期的计时器),然后告诉底层硬件计时器及时中断以服务下一个事件。当这种情况发生时,hrtimers 会调用相关的回调,然后重复该过程。
因此有定时器列表(以树的形式实现),但没有显式的递减计数器,该部分是通过硬件定时器处理的。这部分源代码的主要参考是enqueue_hrtimer().
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)