2012-04-05 3 views
2

Я в рабочем потоке и хочу спать в течение определенного периода времени (обычно несколько сотен миллисекунд), но сон должен прерываться. Вот что я придумалПрерывающий сон в Qt?

void DummyScope::sleepForSamples() { 
    if(m_sampleSleep < 100) { 
     MySleeper::sleep(m_sampleSleep); 
     return; 
    } 

    // sleep in periods of 100 ms, to be responsible for shutdown requests  
    qint64 t = QDateTime::currentMSecsSinceEpoch(); 
    qint64 end = t + m_sampleSleep; 

    while(t + 100 <= end) { 
     MySleeper::sleep(100); 
     t = QDateTime::currentMSecsSinceEpoch(); 

     // TODO: check here whether we are interrupted 
    } 

    if(end > t) { 
     MySleeper::sleep(end - t); 
    } 
} 

Однако, что выглядит немного запутанным, и мне интересно, есть ли лучший способ сделать это. Использует ли QWaitCondition с тайм-аутом лучшего решения?

ответ

2

«Использует QWaitCondition с тайм-аутом - подождите лучшее решение?»

Да!

Петля sleep(), за исключением безотказной работы каждые 100 мс, имеет среднюю задержку прерывания 50 мс.

+0

Можете ли вы дать обоснование/некоторый фон, пожалуйста? Такие вещи, как условия ожидания и мьютексы, звучат как тяжелый материал POSIX. Напротив, в моей петле есть только основные сна. –

+0

Вам не нужен мьютекс, только если «QWaitCondition :: wait (timeout)». –

+0

@ JohannesSchaub-litb Я думаю, это потому, что с помощью таймера ваш процесс никогда не просыпается, а именно планировщик ОС, который обнаруживает, когда ваш процесс должен быть прерван. Кроме того, у этого есть лучшая латентность, с вашим циклом будет средняя латентность вашего таймаута/2, прежде чем вы проснетесь, чтобы обработать событие. – sashoalm

0

Определенно подождите от переменной условия и позвольте сопроводительному условию сказать вам, почему вы были прерваны.
Если вам не нужно использовать QT-потоки, C++ 11 и boost позволяют добавлять предикат wait_for/timed_wait, поэтому побочные пробуждения не испортит ваш таймаут.

Конечно, это еще более убедительно, если вы можете идти дальше на 1 шаг и не беспокоиться о тайм-ауте (если переменная условия может обрабатывать все случаи).

+0

@ JohannesSchaub-litb: Я только что узнал о предикате, проходящем в boost/C++ 11 (если это то, что вы спрашиваете). Qt (и другие реализации, которые я знаю) не имеют. – stefaanv

0

Вы можете подождать прямо на мьютексе с помощью QMutex::tryLock(int timeout), если вы заблокируете и разблокируете его из другого потока.