3

在过去的 20 分钟里,我一直在研究空循环,其目的只是等待条件变为真。

我有一个名为“waitForLoaded”的函数,它是由 CreateThread 创建的线程。

功能:

void waitForLoaded(){
    while(!isLoaded){
        Sleep(500); // < my question
    }
    Sleep(500); //sleep another 500ms to ensure everything is loaded.
    //continue on here
}

我使用 Sleep(500) 在 CPU 上很容易,因为我相信使用 0 或 1 会耗尽处理器。

我在很多人中看到过使用“睡眠(0)”的代码,但我不明白为什么不只是不睡觉,而是做“while(condition){} ..”

我找不到任何关于哪个对 CPU 更友好的可靠答案,所以我在这里问人们,忙等待与 0 毫秒、1 毫秒或 500 毫秒有什么区别,哪个对 CPU 更友好。

在我看来,最好至少睡半场,这几乎不会被用户注意到。

4

4 回答 4

7

在 Windows 上,Sleep(0) 不会花费任何时间休眠,但允许操作系统将 CPU 让给另一个等待线程。这有点像说“如果有人在排队,让他们先去吧,否则我想马上去。”

于 2015-01-15T05:23:22.963 回答
1

围绕事件或类似事物的简单同步原语将消耗更少的 CPU,并且您的线程有望在 500 毫秒等待的最坏情况下比 500 毫秒更快地开始工作。

于 2015-01-15T05:30:56.227 回答
0

首先你需要研究你的问题。

  • 您需要忙碌的等待吗?
  • 可以使用调度员吗?
  • 您能否检测到数据可用或操作完成的确切时刻?

我将研究不同的方法,例如事件文件描述符或条件变量。

条件变量法:

boost::mutex::scoped_lock lock(m_mutex);
while(queue.empty() && !m_quit) {
    m_condition.wait(lock);
}    

事件文件描述符方法

m_loopFD = eventfd(0,EFD_CLOEXEC|EFD_NONBLOCK);
if(m_loopFD < 0) {
    close(m_epollFD);
    throw ...
}
struct epoll_event event;
memset(&event, 0, sizeof(struct epoll_event));
event.data.fd = m_loopFD;
event.events = EPOLLIN;
if(epoll_ctl(m_epollFD, EPOLL_CTL_ADD, m_loopFD, &event) != 0) {
    throw ...
}

以后你可能会有这样的事情

int res = epoll_wait(m_epollFD, events, MAX_EVENTS, timeout);

并唤醒它:

uint64_t value = 0x01;
write(m_loopFD, &value, sizeof(value));
于 2015-01-15T07:48:58.360 回答
0

如果我理解您的问题,您是在问这些等待方法中哪个更好:

  • sleep(500)
  • sleep(1)
  • sleep(0)
  • // (do nothing)

如果你有时间买得起sleep(500),那么答案就是“ sleep(500)

于 2015-01-15T05:25:35.660 回答