如何在等待某些事件时不占用CPU

How not to hog CPU while waiting for some event?

本文关键字:CPU 事件 在等待      更新时间:2023-10-16

我想写一些代码,在某个事件上唤醒(或睡眠直到(某个事件。

我有一段代码,它会休眠,直到某些事件发生,例如当被时钟闹钟时。

伪代码:

int main() {
  TimePoint someTp("3PM");
  std::this_thread::sleep_until(someTP);
}

这是我目前的实现,但这占用了我大约 10% 的 CPU 功率。我认为我的设计有缺陷,有没有更好的解决方案?提前非常感谢!

问题在于调用 sleep_for(..)std::this_thread:sleep_until(..) 的实现,它调用 nanosleep()

(参见 GNU 源代码,第 271 行。

请参阅以下堆栈溢出问题:

  • 纳睡眠高CPU使用率? (调用 nanosleep 的 Linux 高 CPU 问题。
  • boost::this_thread::sleep(( vs. nanosleep((?

您似乎不需要nanosleep()的高分辨率。 您可以使用宽松的开源许可证编写自己的解决方案,并调用sleep()而不是nanosleep().

如果您确实需要亚秒级分辨率,我建议您使用调用select()而不是nanosleep()的技术。 select()旨在非常有效地阻止亚秒级延迟,并且大多数操作系统都足够准确地遵守超时参数,因此它在产生CPU的同时可用于亚秒级计时。

您甚至可以在 error_fds 参数中创建一个套接字来传递给 select(),其中套接字在传递给 close() 并成为"错误"状态套接字时可以用作跨线程"信号"。

更好的解决方案是使用事件驱动的库,如 Boost.Asio 或 libevent,而不是休眠一段时间。

一个简单的实现可以是使用Semaphore

在信号灯上阻止worker thread,并从闹钟事件发生的另一个线程发出semaphore信号。

void* workerThread(void*) 
{
     TimePoint someTp("3PM");
     sem_Wait();    //Thread remains blocked here
}
void timercallback()
{
    sem_post(); //Signals worker thread to move ahead
}