在Linux中,轮询在一个有良知的方式
-
20-09-2019 - |
题
当你有一个紧密环路探询事物的状态,我不太知道怎么做轮询没有想要使用CPU其他进程的方式获得。例如,这样做的:
while (state == BUSY) state = check_state();
好像资源的浪费。我认为要做到这一点的最好办法是:
while (state == BUSY) {
sched_yield();
state = check_state();
}
我期望顶部将列出过程睡觉,即使它消耗CPU的100%它这样做一段时间。这样一来,这一进程将(我希望)民意调查“很好”。但是,这不会发生什么变化。目前我
while (state == BUSY) {
sleep(1);
state = check_state();
}
这是完全可以接受的,但我觉得这是可以做到比这更好的。是否有一个标准的做法这样做呢?
解决方案
不要SCHED_YIELD()旋转,它渣土了调度程序的优先级检测非常糟糕,甚至当它从性能的角度进行互操作以及会做这样的事情残骸的电池寿命和功耗指标。如果您的应用程序可以容忍的等待时间,轮询超时(甚至短的像为10Hz)非常受欢迎得多,如果仍然不理想。
在正确的答案取决于什么check_state()实际上需要做的。你真的确认你不能安排你的事情让你的状态变化是内核可见的事件,你可以阻止呢?
其他提示
遗憾的是,作为有良心投票没有这样的事情。轮询总是反应时间和资源消耗之间的权衡:轮询周期越短,越好的反应时间,但较高的资源消耗。轮询周期越长,就越能节省您的,但反应性较低的应用程序变得。
轮询总是丑陋的,不管你如何看待它。如果你正在试图做的事情以正确的方式,你必须使用一个更好的机制,即通知。 这也就意味着,你的check_state()API是一个坏的,因为它不仅可以让你轮询的状态;你需要设计再通知你,状态变化时的功能。典型地,这样的功能将使得一些的fd可读当状态变化,所以可以同步或异步地等待在FD的事件,并且仅当这样的事件发生时醒来。
在我的实时工作,我通常选择一个合理的超时(例如为10μs),和旋涂的条件和RDTSC(时间戳计数器)。
如果你想旋转的时间(如超过10毫秒)真的很长时间,我建议把一个小的睡眠声明有那么其他的东西,得到一些机会运行。