2016-04-14 2 views
3

Мне нужно выполнить некоторую функцию, точную в 20 миллисекундах (для отправки пакетов RTP) после некоторого события. Я попытался следующие варианты:Подождите с точностью до 20 миллисекундов

std::this_thread::sleep_for(std::chrono::milliseconds(20)); 
boost::this_thread::sleep_for(std::chrono::milliseconds(20)); 
Sleep(20); 

также различные извращения, как:

auto a= GetTickCount(); 
while ((GetTickCount() - a) < 20) continue; 

также попытался микро- и наносекунд.
Все эти методы имеют ошибку в диапазоне от -6ms до +12ms, но ее неприемлемы. Как заставить его работать правильно?

Мое мнение, что + -1ms приемлемо, но не более.

Update1: для измерения времени прошло я использую std::chrono::high_resolution_clock::now();

+0

Вы используете поток и таймер для этого? – ChrisF

+0

Вы уверены, что таймер для измерения ожидаемого времени является точным? – MikeCAT

+0

Какие ОС включены? – antiHUMAN

ответ

1

std::chrono::steady_clock Используя, я получил о точности 0,1 мс на окнах 7.

То есть, просто:

auto a = std::chrono::steady_clock::now(); 
while ((std::chrono::steady_clock::now() - a) < WAIT_TIME) continue; 

Это должно дать вам точные "ожидания" (около 0,1 мс, а Я сказал), по крайней мере. Мы все знаем, что такой вид ожидания «уродлив», и его следует избегать, но это взломать, что все равно может сделать трюк.

Вы можете использовать high_resolution_clock, которые могли бы дать еще большую точность для некоторых систем, но не гарантировано быть отрегулированным ОС, и вы не хотите этого. Предполагается, что steady_clock не будет регулироваться, и часто имеет ту же точность, что и high_resolution_clock.

Что касается функций «sleep()», которые являются очень точными, я не знаю. Возможно, кто-то еще знает об этом больше.

+0

Вы используете 'this_thread :: sleep_for (std :: chrono :: milliseconds (n));' или что-то еще? – Dmitry

+0

Нет, я не использовал его для сна, но для измерения скорости выполнения некоторого кода. Дело в том, что у вас есть точная точность, если вы используете это. Когда дело доходит до точности «спит», я не знаю, но их можно избежать, правильно? Ваша вторая версия даст вам необходимую вам точность. – antiHUMAN

3

Вкратце, из-за того, как ядра ОС управлять временем и темы, вы не получите точность намного лучше с этим методом. Кроме того, вы не можете полагаться на сон в одиночку со статическим интервалом, или ваш поток быстро сместит вашу запланированную тактовую передачу, потому что поток может быть прерван или он может быть запланирован снова после вашего сна ... по этой причине вы должны проверить системные часы, чтобы знать, сколько спать на каждой итерации (т.е. где-то между 0 мс и 20 мс). Не вдаваясь в подробности, это также объясняет, почему в потоках RTP есть буфер дрожания ... для учета изменений в приеме пакетов (из-за джиттера сети или отправки дрожания). Из-за этого вам, вероятно, не понадобится точность +/- 1 мс.

1

В C у нас есть ненасыщенная функция во времени.h.

Функция nanosleep() вызывает приостановку текущего потока до тех пор, пока не истечет временной интервал, заданный аргументом rqtp, или сигнал доставляется в вызывающий поток, и его действие заключается в вызове функции захвата сигнала или прекратить процесс.

Эта программа работает в течение 20 миллисекунд.

int main() 
{ 
    struct timespec tim, tim2; 
    tim.tv_sec = 0; 
    tim.tv_nsec =20000000;//20 milliseconds converted to nano seconds 

    if(nanosleep(&tim , NULL) < 0) 
    { 
     printf("Nano sleep system call failed \n"); 
     return -1; 
    } 

    printf("Nano sleep successfull \n"); 
return 0; 
} 
+2

Для чего это платформа? – Dmitry

+1

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и/или как он отвечает на вопрос, значительно улучшит его долгосрочную ценность. Пожалуйста, отредактируйте свой ответ, чтобы добавить какое-то объяснение. – CodeMouse92

Смежные вопросы