在Linux中,以认真的方式进行轮询

发布于 2024-08-06 12:00:32 字数 488 浏览 8 评论 0 原文

当你有一个紧密的循环来轮询某个东西的状态时,我不太确定如何在不妨碍其他想要使用 CPU 的进程的情况下进行轮询。例如,这样做:

while (state == BUSY) state = check_state();

似乎是浪费资源。我认为最好的方法是:

while (state == BUSY) {
    sched_yield();
    state = check_state();
}

我希望 top 会将进程列为睡眠进程,即使它在执行此操作时确实消耗了 100% 的 CPU。这样,该过程将(我希望)“很好地”进行轮询。但事实并非如此。目前我已经

while (state == BUSY) {
    sleep(1);
    state = check_state();
}

完全可以接受,但我觉得可以做得比这更好。这样做有标准做法吗?

When you've got a tight loop polling the status of something, I'm not quite sure how to do the polling without getting in the way of other processes wanting to use the CPU. For instance, doing this:

while (state == BUSY) state = check_state();

seems like a waste of resources. I would think the best way to do this would be:

while (state == BUSY) {
    sched_yield();
    state = check_state();
}

I'd expect that top would list the process as sleeping, even if it does consume 100% of the CPU while it's doing this. This way, the process would (I hope) poll "nicely". But that's not what happens. At the moment I have

while (state == BUSY) {
    sleep(1);
    state = check_state();
}

which is perfectly acceptable, but I feel like it could be done better than this. Is there a standard practice for doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

日久见人心 2024-08-13 12:00:32

不要使用 sched_yield(),它会严重扰乱调度程序的优先级检测,即使从性能角度来看它具有良好的互操作性,也会造成电池寿命和功耗指标等问题。如果您的应用程序可以容忍延迟,那么超时轮询(即使是 10Hz 之类的短轮询)也是非常可取的,尽管这仍然不理想。

正确的答案取决于 check_state() 实际需要做什么。您是否绝对确定您无法安排一些事情,以便您的状态更改成为您可以阻止的内核可见事件?

Don't spin on sched_yield(), it mucks up the scheduler's priority detection very badly and even when it interoperates well from a performance perspective will do things like wreck battery life and power consumption metrics. If your application can tolerate the latencies, polling with a timeout (even short ones like 10Hz) is very much preferable, if still not ideal.

The right answer depends on what check_state() actually needs to do. Are you absolutely sure you can't arrange things so that your state changes are kernel-visible events that you can block on?

丶视觉 2024-08-13 12:00:32

我不认为这是你可以使用的东西 pollepoll 上?

I don't suppose this is something you can use poll or epoll on?

一梦等七年七年为一梦 2024-08-13 12:00:32

不幸的是,不存在认真投票这样的事情。轮询始终是反应时间和资源消耗之间的权衡:轮询周期越短,反应时间越好,但资源消耗越高。轮询周期越长,节省的能源就越多,但应用程序的反应性就越低。

不管你怎么看,投票总是丑陋的。如果您尝试以正确的方式做事,则必须使用更好的机制,即通知。
这意味着你的 check_state() API 是一个糟糕的 API,因为它只允许你轮询状态;您需要一个旨在在状态更改时通知您的函数。通常,这样的函数会在状态改变时使某些 fd 可读,因此您可以同步或异步等待 fd 上的事件,并且仅在此类事件发生时唤醒。

Unfortunately, there's no such thing as conscientious polling. Polling is always a trade-off between reaction time and resource consumption: the shorter the polling period, the better the reaction time but the higher the resource consumption. The longer the polling period, the more energy you save but the less reactive your application becomes.

Polling is always ugly, no matter how you look at it. If you're trying to do things the right way, you'll have to use a better mechanism, i.e. notification.
What that means is that your check_state() API is a bad one, because it only allows you to poll for the state; you need a function designed to notify you when the state changes. Typically, such a function would make some fd readable when the state changes, so you can synchronously or asynchronously wait for events on the fd, and only wake up when such an event occurs.

满地尘埃落定 2024-08-13 12:00:32

我认为你可以使用 libeventlibev

两者都提供了处理此类事情的设施。

I think you could use libevent or libev.

Both provide facilities for handling things like this.

回忆那么伤 2024-08-13 12:00:32

在我的实时工作中,我通常会选择一个合理的超时(例如 10us),并根据条件和 RDTSC(时间戳计数器)进行旋转。

如果你想旋转很长一段时间(比如超过 10 毫秒),我建议在那里放置一个小的睡眠语句,以便其他东西有机会运行。

In my realtime work, I typically pick a reasonable timeout (like 10us), and spin on the condition and RDTSC (the time stamp counter).

If you want to spin for really long periods of time (like longer than 10ms), I'd suggest putting a small sleep statement in there so other stuff gets some chance to run.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文