空循环等待条件(忙等待)

时间:2015-01-15 05:16:42

标签: c++ while-loop conditional-statements sleep busy-waiting

我花了最后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更友好的答案,所以我在这里问人们,忙碌等待0ms,1ms或500ms之间有什么区别,哪个更适合CPU。

在我看来,最好做至少一半的睡眠,这是用户几乎无法察觉的。

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

围绕事件或类似事件的简单同步原语会耗尽较少的CPU,并且您的线程有望比500 ms等待的最差情况500毫秒更快地开始工作。

答案 2 :(得分:0)

如果我理解你的问题,你就会问这些等待方法哪个更好:

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

如果您有时间负担sleep(500),那么答案就是&#34; sleep(500)&#34;

答案 3 :(得分: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));