据我所知,您编写的Linux守护程序可以无限循环地监听请求 像...这样的东西。
int main() {
while(1) {
//do something...
}
}
参考:http://www.thegeekstuff.com/2012/02/c-daemon-process/
我读到睡眠程序使其进入等待模式,因此它不会占用资源。
1.如果我希望我的守护进程每1秒检查一次请求,以下是否会消耗资源?
int main() {
while(1) {
if (request) {
//do something...
}
sleep(1)
}
}
2.如果我要移除睡眠,是否意味着CPU消耗将增加100%?
3.是否可以在不吃资源的情况下运行无限循环?说..如果它什么都不做,只是循环自己。或者只是睡觉(1)。
无尽的循环和CPU资源对我来说是一个谜。
答案 0 :(得分:13)
是否可以在不吃资源的情况下运行无限循环?说..如果它什么都不做,只是循环自己。或者只是睡觉(1)。
有一个更好的选择。
您可以使用信号量,它在循环开始时仍然被阻止,并且您可以在需要循环执行时发出信号量信号。
请注意,这不会占用任何资源。
答案 1 :(得分:13)
poll
和select
调用(Basile Starynkevitch在评论中提到)或信号量(Als在答案中提到)是等待请求的正确方法,具体取决于具体情况。在没有poll
或select
的操作系统上,应该有类似的内容。
由于以下原因,sleep
,YieldProcessor
和sched_yield
都不是正确的方法。
YieldProcessor
和sched_yield
只是将进程移动到可运行队列的末尾,但让它可以运行。结果是它们允许执行具有相同或更高优先级的其他进程,但是,当这些进程完成时(或者如果没有),则调用YieldProcessor
或sched_yield
的进程继续跑。这导致两个问题。一个是较低优先级的进程仍然无法运行。另一个原因是,这会导致处理器始终使用能量运行。我们希望操作系统能够识别何时不需要运行任何进程并将处理器置于低功耗状态。
sleep
可能会允许这种低功耗状态,但它会在下一个请求进入之前进行一次猜谜游戏,它会在没有需要时重复唤醒处理器,并且它会使处理对请求的响应较少,因为即使有请求服务,进程也将继续睡眠,直到请求的时间到期为止。
poll
和select
来电正是针对这种情况而设计的。它们告诉操作系统该进程希望为其I / O通道之一上的请求提供服务,否则无需做任何工作。这允许操作系统将进程标记为不可运行,并在适当的情况下将处理器置于低功耗状态。
使用信号量提供相同的行为,除了唤醒进程的信号来自另一个引发信号量的进程而不是I / O通道中出现的活动。信号量适用于做某事的信号以这种方式到达;只需使用poll
中的任何一个或信号量更适合您的情况。
poll
,select
或信号量导致内核模式调用的批评是无关紧要的,因为其他方法也会导致内核模式调用。一个过程本身无法入睡;它必须调用操作系统来请求它。同样,YieldProcessor
和sched_yield
向操作系统发出请求。
答案 2 :(得分:2)
简短的回答是肯定的 - 删除睡眠会产生100%的CPU - 但答案取决于一些额外的细节。它会消耗它可以获得的所有CPU,除非......
编辑:对于您的方案,我支持@Als提出的建议。
编辑2:我希望这个答案收到-1,因为我声称阻止操作实际上是一个好主意。 [如果你-1,你应该在评论中留下动力,这样我们都可以学到一些东西。]
目前流行的想法是非阻塞(基于事件的)IO是好的,阻塞是坏的。此视图过于简化,因为它假定所有执行IO的软件都可以通过使用非阻塞操作来提高吞吐量。
什么?我是否真的建议使用非阻塞IO实际上可以降低吞吐量?是的,它可以。当一个进程为单个活动提供服务时,实际上最好使用阻塞IO,因为阻塞IO只会消耗在进程存在时已经支付的资源。
相比之下,非阻塞IO可以承载比简单阻塞IO更大的固定开销。如果该进程无法提供可以交错的其他IO,那么通过支付非阻塞设置就没有任何好处。 (实际上,不合适的非阻塞IO的最大成本仅仅在于增加的代码复杂性。除此之外,这个主题主要是一个思考练习。)
在阻止IO的情况下,我们依靠操作系统来安排可以取得进展的进程。这就是操作系统的目的。
在非阻塞IO下,我们有更高的设置成本,但可以在交错工作之间共享进程及其线程的资源。因此,非阻塞IO非常适用于为多个独立活动(例如Web服务器)提供服务的任何进程。获得的吞吐量远远优于非阻塞IO的固定成本开销。