Пустой цикл, который ожидает условия (занято-ожидание)

Я потратил последние 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) для облегчения работы процессора, так как считаю, что использование 0 или 1 приведет к опустошению процессора.

Я видел у многих людей код «Sleep (0)», используемый, и я никогда не понимал, почему бы просто не спать вообще и делать «while (условие) {} ..»

Я не могу найти какого-либо четкого ответа, который более дружествен к процессору, поэтому я спрашиваю людей, в чем разница между ожиданием занятости с 0 мс, 1 мс или 500 мс и тем, что более дружественно к процессору.

На мой взгляд, было бы лучше сделать хотя бы половину сна, что почти незаметно для пользователя.

1

Решение

В Windows Sleep (0) не будет тратить время на сон, но позволяет ОС передавать ЦП другому ожидающему потоку. Это все равно что сказать: «Если кто-то ждет в очереди, пусть он идет вперед, иначе я бы хотел пойти прямо сейчас».

5

Другие решения

Простой примитив синхронизации вокруг события или что-то в этом роде потребляет меньше ресурсов ЦП, и, как мы надеемся, ваш поток начнет работать быстрее, чем наихудший случай, 500 мс с ожиданием 500 мс.

1

Если я понимаю ваш вопрос, вы спрашиваете, какой из этих методов ожидания превосходит:

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

Если у вас есть время, чтобы позволить себе sleep(500)тогда ответ «sleep(500)«

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));
0