![通过时钟唤醒守护进程](https://linux22.com/image/1107137/%E9%80%9A%E8%BF%87%E6%97%B6%E9%92%9F%E5%94%A4%E9%86%92%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B.png)
我正在编写一个守护进程(我的第一个守护进程),它需要每秒唤醒一次并检查一个特殊的硬件。我让它检查硬件,但我如何让它休眠,然后在特定的一秒唤醒?
我想以某种方式连接到时钟并使用某种中断唤醒。轮询是不可能的,因为我不想在空闲时浪费计算机资源。
- 帕斯卡
- Ubuntu 服务器 10.10
- 无OOP
答案1
好吧,这是我想到的解决方案。虽然有点麻烦,但是……
首先,当我准备等待下一秒时,我会得到当前的毫秒数。这是我能从系统获得的最精细的分辨率。
然后,我从 1000(每秒 1000 毫秒)中减去该值,再减去当前毫秒,就等于我需要等待的毫秒数。
然后将其乘以 100 万(转换为纳秒)
然后使用 NanoSleep(blah,blah)。
这似乎有效。
PS,我比较了这种方法和简单地轮询等待下一秒到来的方法的 CPU 使用率(使用 top),轮询版本使用了 98% 的 CPU,而这种方法只使用了 0.3%。这就是方法。
答案2
在一个地方,你说你想在某一秒进行轮询。在另一个地方,你说你想每秒进行轮询。是哪一个?
我认为最简单的方法是将其安排在程序循环[1]本身中。我不懂 Pascal,但它肯定有某种睡眠功能。
下面是一些伪代码,可以帮助您了解这一点:
while(true) {
check_hardware()
sleep(1) //unit is seconds
}
如果您只想在特定的某一秒运行,只需添加对该秒的检查:
while(true) {
if(get_time_as_seconds() in allowable_seconds()) {
check_hardware()
}
sleep(1)
}
[1]:也就是说,在你的守护进程中。
答案3
查看alarm
系统调用和SIGALRM
处理程序以及pause
。我不知道如何在 Pascal 中做到这一点,但大概会类似。
man 2 alarm
man 3 sleep
您可能会发现这sleep
已经足够满足您的需求了。事实上,文档中说这甚至可以使用alarm
(尽管我相信在 Linux 中不行)来实现。
请注意,所有这些因素都不能保证您确切的醒来时间。给出的时间是近似值。闹钟不会发送前给定的时间,但可能会交付一点晚的。Sleep 有类似的问题,但如果进程收到另一个信号,也可能会提前返回。