Как не перегружать процессор во время ожидания какого-либо события? - PullRequest
6 голосов
/ 09 июня 2011

Я хотел бы написать какой-нибудь код, который просыпается (или спит) до какого-то события.

У меня есть фрагмент кода, который спит, пока не произойдет какое-либо событие, например, когда его тревожат часы.

Псевдокод:

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

Это моя текущая реализация, но она потребляет около 10% мощности моего процессора.Я думаю, что мой дизайн имеет недостатки, есть ли лучшее решение для этого?Большое спасибо заранее!

Ответы [ 3 ]

8 голосов
/ 09 июня 2011

Проблема в реализации std::this_thread:sleep_until(..), которая вызывает sleep_for(..), которая вызывает nanosleep().

(см. gnu sources , строка 271.)

См. Следующие вопросы по Stackoverflow:

Похоже, вам не нужно высокое разрешение nanosleep().Вы можете написать собственное решение с разрешительной лицензией с открытым исходным кодом и позвонить по номеру sleep() вместо nanosleep().

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

Вы можете дажесоздайте сокет с целью перехода к select(), в параметре error_fds, где сокет может использоваться как перекрестный поток "сигнал", когда он передается в close() и становится сокетом состояния "ошибка".

3 голосов
/ 09 июня 2011

Лучшим решением было бы использование библиотеки, управляемой событиями, такой как Boost.Asio или libevent , а не спящий в течение некоторого времени.

1 голос
/ 09 июня 2011

Простая реализация может состоять в использовании 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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...