Как заставить поток спать меньше миллисекунды в Windows

В Windows у меня есть проблема, с которой я никогда не сталкивался в Unix. Вот как перевести поток в спящий режим менее чем на одну миллисекунду. В Unix у вас обычно есть несколько вариантов (сон, usleep и nanosleep) в соответствии с вашими потребностями. В Windows, однако, есть только спящий режим с точностью до миллисекунды.

В Unix я могу использовать системный вызов select для создания микросекундного сна, что довольно просто:

int usleep(long usec)
{
    struct timeval tv;
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, 0, &tv);
}

Как я могу добиться того же в Windows?


person Jorge Ferreira    schedule 17.09.2008    source источник
comment
Это не работает в Windows. Минимальное время ожидания при выборе по-прежнему составляет около 1 мс (Vista, поток RT, timeBeginPeriod (1), MMCSS Pro Audio RT Critical).   -  person Robert    schedule 20.07.2011
comment
Это связано с тем, что большинство компьютеров, на которых работает Windows, имеют аппаратные ограничения в диапазоне 1-10 мс. Компьютерное оборудование для ПК стоит дешево. У вас должно быть специальное оборудование, чтобы следить за точным временем. Например, карты Wi-Fi: время передачи маяка в миллисекундах должно оставаться аппаратным (даже в Linux) из-за ненадежности хронометража ПК.   -  person unixman83    schedule 22.09.2011
comment
Linux может работать на сложных и встроенных устройствах, что обеспечивает лучшую детализацию, чем большинство ПК с Windows. Само ядро ​​с открытым исходным кодом также легко настраивается. Его планировщик можно сделать операционной системой почти реального времени. Следовательно, потребность в nanosleep().   -  person unixman83    schedule 22.09.2011
comment
Возможный дубликат Требуется точный спящий режим потока. Ошибка макс. 1 мс   -  person ivan_pozdeev    schedule 12.08.2017


Ответы (18)


Это указывает на неправильное понимание функций сна. Передаваемый вами параметр - минимальное время для сна. Нет гарантии, что поток проснется точно в указанное время. Фактически, потоки вообще не «просыпаются», а выбираются для выполнения планировщиком ОС. Планировщик может выбрать ожидание намного дольше, чем запрошенная продолжительность сна, чтобы активировать поток, особенно если другой поток все еще активен в этот момент.

person Joel Coehoorn    schedule 17.09.2008
comment
Да, Sleep () означает просто подсказку. Согласно MSDN время Sleep () на самом деле может быть меньше, чем вы запрашиваете. Это просто руководство для ОС по повышению производительности, а не хороший механизм синхронизации при любой степени детализации. - person unixman83; 22.09.2011
comment
Однако гарантию можно получить при тщательной реализации. Правильная установка приоритетов потоков / процессов и сходства процессоров обсуждаются здесь. - person Arno; 26.09.2012
comment
Здесь есть серьезная дезинформация: параметр, который вы передаете, - это минимальное время сна. Не верно для окон: msdn.microsoft.com/en-gb/library/windows/desktop/ Если dwMilliseconds меньше разрешения системных часов, поток может находиться в спящем режиме меньше указанной длины. времени. Если dwMilliseconds больше одного тика, но меньше двух, ожидание может составлять от одного до двух тиков и так далее. - person Roddy; 07.11.2012
comment
Отличный ответ на несуществующий вопрос. Несмотря на то, что все ответы ни на один вопрос верны, этот действительно хорош. - person Kenyakorn Ketsombut; 11.09.2013
comment
Это просто не отвечает на вопрос. Это хороший ответ на другой вопрос, поэтому я очень не хочу давать вам голос против, но слишком многие ошибочно проголосовали за вас. Если бы вы сказали, что не можете, и вот почему вы бы ответили на этот вопрос. - person John Thoits; 25.01.2019

Как говорит Джоэл, вы не можете осмысленно «спать» (т.е. отказываться от запланированного CPU) в течение таких коротких периодов времени. Если вы хотите отложить на какое-то короткое время, вам нужно вращаться, неоднократно проверяя таймер с подходящим высоким разрешением (например, «таймер производительности») и надеясь, что что-то с высоким приоритетом все равно вас не упустит.

Если вы действительно заботитесь о точных задержках в такие короткие промежутки времени, вам не следует использовать Windows.

person Will Dean    schedule 17.09.2008
comment
-1 за то, что не учитывает, что пользователь приложения может иметь другие предпочтения, чем разработчики. - person Austin Mullins; 12.06.2014
comment
@AustinMullins Не могли бы вы немного рассказать об этом? Вы искали какое-нибудь заявление о пороках занятого прядения? - person Will Dean; 18.06.2014
comment
Нет, я имел в виду, что вы не должны использовать примечание Windows. Разработчик должен делать программы для пользователя, который, вероятно, хочет, чтобы программа работала в Windows. - person Austin Mullins; 18.06.2014
comment
О, я вижу. Что ж, если разработчик или его пользователи предвидят требование жесткого реального времени, как описано в вопросе, то Windows не та ОС, которую им следует пытаться использовать. Это не уничижительный комментарий к Windows и не лицензия на высокомерие разработчиков, это просто мнение о технической пригодности, которое (как разработчик Windows :-) я рад поддержать. - person Will Dean; 18.06.2014
comment
Я один из разработчиков, который вынужден использовать окна, потому что нашему приложению необходимо взаимодействовать с другим, доступным также в Windows. После моих тестов я согласен с этим решением, которое дало нам наилучшие результаты, но я категорически не согласен с вашим последним предложением: вы не должны использовать Windows: вы не можете знать, почему разработчику нужно спать в течение менее миллисекунд. . Есть даже целый проект об этом здесь - person gog; 24.09.2018
comment
@gog - Вы не можете надежно засыпать (или задерживать любым другим способом) на такое короткое время в Windows (кроме, возможно, написания драйвера режима ядра). Неважно, какие коммерческие или прагматические требования делают Windows хорошим выбором, она просто не предназначена для такого рода вещей. Как я неоднократно повторял за 10 лет, прошедших с тех пор, как я написал первоначальный ответ, это не критика, это наблюдение. Ваш жесткий цикл может большую часть времени ждать нужного времени, но иногда он будет ждать дольше, и если вы не могли когда-либо терпеть это, значит, вы не могли использовать Windows. - person Will Dean; 24.09.2018
comment
@WillDean Но, используя ваше решение (QueryPerformanceCounter), я смог спать в течение микросекунд в Windows, так же, как это доступно в Unix. Это исходный вопрос. Вопрос не в том, что касается ОСРВ, когда приложение не может долго спать. Даже Sleep () не может этого гарантировать. И даже ядро ​​Linux в стандартных дистрибутивах не гарантирует этого. Я думаю, что последнее предложение не относится к этому ответу, даже если я проголосовал за него. - person gog; 27.09.2018

Используйте мультимедийные таймеры с высоким разрешением, доступные в winmm.lib. См. Пример this.

person Joe Schneider    schedule 17.09.2008
comment
Я удивлен, что за это не проголосовали больше. Это реальное решение. Почему все голосуют за то, что Sleep - это всего лишь предположение и перестать использовать Windows, перейти на Unix? Я признаю, что полезно понимать, что сон - это всего лишь предположение, но это не решение. И не у всех есть возможность выйти из Windows. Чтобы быть ясным, это решение дает вам точность только 1 мс (с использованием библиотеки мультимедиа). Это то что мне нужно. Я не пробовал метод выбора (опубликованный Hendrick & smink), но похоже, что он может снизить точность до субмиллисекунд. - person Gabe Halsmer; 08.08.2015
comment
Связанный код @GabeHalsmer может ждать только 1 или более мсек, это не то, о чем спрашивают. Более того, он не компилируется из коробки, содержит ошибки и не является потокобезопасным и может либо вызывать взаимоблокировки, либо вообще не ждать. Даже после исправления некоторых проблем, чтобы заставить его делать то, что он должен делать, и просить его подождать 1 мс, я видел, как он ждал где-то от 1 до 3 мс, и это были просто быстрые тесты в системе без большой нагрузки. Таким образом, он работает не лучше, а хуже, чем way более простая комбинация WaitableTimer / WaitForSingleObject, которая, по крайней мере, выполняет ожидания sub-mSec. Итак: не совсем подходящее решение для всех. - person stijn; 10.05.2017
comment
Все комментарии, относящиеся к Linux, должны быть отмечены и удалены. @Gabe, вы правы, пользователи ОС с рыночной долей в 1% часто пытаются шуметь. - person Michael Chourdakis; 23.07.2020

#include <Windows.h>

static NTSTATUS(__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(BOOL, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
static NTSTATUS(__stdcall *ZwSetTimerResolution)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG)) GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwSetTimerResolution");

static void SleepShort(float milliseconds) {
    static bool once = true;
    if (once) {
        ULONG actualResolution;
        ZwSetTimerResolution(1, true, &actualResolution);
        once = false;
    }

    LARGE_INTEGER interval;
    interval.QuadPart = -1 * (int)(milliseconds * 10000.0f);
    NtDelayExecution(false, &interval);
}

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

person Oskar Dahlberg    schedule 14.07.2015
comment
Интересный факт: timeBeginPeriod / timeEndPeriod внутренне использует ZwSetTimerResolution, и еще один интересный факт - минимальное временное разрешение составляет 0,5 мс, с timeBeginPeriod вы получите минимум 1 мс, но с ZwSetTimerResolution вы можете получить 0,5 мс, поэтому вызов ZwSetTimerResolution с 1 эквивалентен его вызову. с 5000 и ниже. (Это в блоке 100 нс, или ограничении 10 МГц) - person rez; 24.12.2020
comment
действительно ли NtDelayExecution освобождает загрузку процессора и использует его для работы с другими потоками? - person iperov; 29.06.2021

Да, вам нужно понимать кванты времени вашей ОС. В Windows вы даже не получите время разрешения 1 мс, если не измените квант времени на 1 мс. (Используя, например, timeBeginPeriod () / timeEndPeriod ()) Это все равно ничего не гарантирует. Даже небольшая загрузка или один дрянной драйвер устройства все скинут.

SetThreadPriority () помогает, но довольно опасно. Плохие драйверы устройств по-прежнему могут вас испортить.

Вам нужна сверхуправляемая вычислительная среда, чтобы эта уродливая штука вообще работала.

person darron    schedule 17.09.2008
comment
Вы просто должны быть осторожны, чтобы не зацикливаться, иначе другие процессы будут голодны ... - person rogerdpack; 16.11.2019
comment
Я в основном говорил о других вещах, которые вы здесь не контролируете. Довольно легко получить что-то, что работает на одном компьютере, полностью выйдет из строя на другом, потому что плохой драйвер устройства держится слишком долго. Если вы разрабатываете что-то для внутреннего использования, это нормально ... если вам нужно что-то, что вы можете выпустить в мир, это действительно болезненно. - person darron; 14.12.2019

Обычно сон длится, по крайней мере, до следующего системного прерывания. Однако это зависит от настроек ресурсов мультимедийного таймера. Может быть установлено значение, близкое к 1 мс, некоторые аппаратные средства даже позволяют работать с периодами прерывания 0,9765625 (ActualResolution, предоставленный NtQueryTimerResolution, покажет 0,9766, но это на самом деле неверно. Они просто не могут поставить правильный число в формате ActualResolution. Это 0,9765625 мс при 1024 прерываниях в секунду).

Есть одно исключение, которое позволяет нам избежать того факта, что может быть невозможно спать меньше периода прерывания: это знаменитый Sleep(0). Это очень мощный инструмент, и он используется не так часто, как следовало бы! Он отказывается от напоминания о временном интервале потока. Таким образом, поток остановится до тех пор, пока планировщик не заставит поток снова получить службу процессора. Sleep(0) - асинхронная служба, вызов заставит планировщик реагировать независимо от прерывания.

Второй способ - использовать waitable object. Функция ожидания, такая как WaitForSingleObject(), может ждать события. Чтобы поток спал в течение любого времени, в том числе в микросекундном режиме, потоку необходимо настроить некоторый служебный поток, который будет генерировать событие с желаемой задержкой. «Спящий» поток настроит этот поток, а затем остановится в функции ожидания, пока служебный поток не установит событие с сигналом.

Таким образом, любой поток может «спать» или ждать в любое время. Сервисный поток может быть очень сложным и предлагать общесистемные сервисы, такие как синхронизированные события с микросекундным разрешением. Однако разрешение в микросекундах может вынудить поток службы вращаться на службе времени с высоким разрешением не более одного периода прерывания (~ 1 мс). Если проявить осторожность, он может работать очень хорошо, особенно в многопроцессорных или многоядерных системах. Вращение в одну мс не сильно повредит многоядерной системе, когда маска сродства для вызывающего и служебного потоков тщательно обрабатывается.

Код, описание и тестирование можно найти на сайте Windows Timestamp Project.

person Arno    schedule 12.07.2012

Как указали несколько человек, сон и другие связанные функции по умолчанию зависят от «системного тика». Это минимальная единица времени между задачами ОС; например, планировщик не будет работать быстрее этого. Даже в ОС реального времени системный тик обычно составляет не менее 1 мс. Хотя он настраивается, это имеет последствия для всей системы, а не только для вашей функции сна, потому что ваш планировщик будет работать чаще и потенциально увеличивать накладные расходы вашей ОС (количество времени для запуска планировщика по сравнению с количеством время выполнения задачи).

Решением этой проблемы является использование внешнего высокоскоростного тактового устройства. Большинство систем Unix позволяют вам указывать свои таймеры и такие разные часы для использования, в отличие от системных часов по умолчанию.

person mbyrne215    schedule 17.09.2008

Если вам нужна такая степень детализации, вы находитесь не в том месте (в пространстве пользователя).

Помните, что если вы находитесь в пользовательском пространстве, ваше время не всегда точно.

Планировщик может запускать ваш поток (или приложение) и планировать его, поэтому вы зависите от планировщика ОС.

Если вы ищете что-то точное, вам нужно пойти: 1) В пространство ядра (например, драйверы) 2) Выбрать RTOS.

В любом случае, если вы ищете некоторую детализацию (но помните о проблеме с пользовательским пространством), посмотрите на функции QueryPerformanceCounter и QueryPerformanceFrequency в MSDN.

person user16523    schedule 17.09.2008

Что вы ждете, что требует такой точности? В общем, если вам необходимо указать этот уровень точности (например, из-за зависимости от некоторого внешнего оборудования), вы используете неправильную платформу и должны смотреть на ОС реального времени.

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

person Rob Walker    schedule 17.09.2008

Фактически использование этой функции usleep приведет к большой утечке памяти / ресурсов. (в зависимости от того, как часто звонят)

используйте эту исправленную версию (извините, не можете редактировать?)

bool usleep(unsigned long usec)
{
    struct timeval tv;
    fd_set dummy;
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    FD_ZERO(&dummy);
    FD_SET(s, &dummy);
    tv.tv_sec = usec / 1000000ul;
    tv.tv_usec = usec % 1000000ul;
    bool success = (0 == select(0, 0, 0, &dummy, &tv));
    closesocket(s);
    return success;
}
person Hendrik    schedule 19.09.2009
comment
Вам не нужно создавать сокет только для того, чтобы иметь возможность вызывать select () - person Jon Watte; 09.09.2012
comment
Я исправил образец кода. Имейте в виду, что вам нужно вызвать WSAStartup / WSACleanup до / после использования этой функции при кодировании под Windows. - person Max Truxa; 07.08.2013

У меня такая же проблема, и ничто не работает быстрее, чем мс, даже Sleep (0). Моя проблема заключается в связи между клиентским и серверным приложением, где я использую функцию _InterlockedExchange для тестирования и установки бита, а затем я сплю (0).

Мне действительно нужно выполнять тысячи операций в секунду таким образом, и он работает не так быстро, как я планировал.

Поскольку у меня есть тонкий клиент, имеющий дело с пользователем, который, в свою очередь, вызывает агента, который затем разговаривает с потоком, я скоро перейду к объединению потока с агентом, чтобы интерфейс событий не требовался.

Чтобы вы, ребята, поняли, насколько медленным является этот сон, я провел тест в течение 10 секунд, выполнив пустой цикл (получилось что-то вроде 18 000 000 циклов), тогда как при наличии события у меня было только 180 000 циклов. То есть в 100 раз медленнее!

person Community    schedule 13.05.2009
comment
Меня не удивляет. Поскольку пустой цикл будет выполняться во внутреннем кэше процессора, когда он пуст. Меня не удивит, если компилятор даже оптимизирует цикл и просто выдаст вам результат. Лучший тест, который на самом деле что-то делает в обоих случаях, и сравнивает результат. попробуйте выполнить _InterlockedIncrement (внутренний) при каждом взаимодействии обоих циклов. - person rxantos; 06.08.2015

Попробуйте использовать SetWaitableTimer. ..

person andrewrk    schedule 03.07.2015

Как уже упоминалось, действительно нет никаких гарантий относительно времени сна. Но никто не хочет признавать, что иногда в простаивающей системе команда usleep может быть очень точной. Особенно с бестикальным ядром. Он есть в Windows Vista, а в Linux - начиная с версии 2.6.16.

Бесконтактные ядра существуют, чтобы помочь улучшить жизнь ноутбуков: ср. Утилита Intel powertop.

В этом состоянии мне довелось измерить команду Linux usleep, которая очень точно соблюдает запрошенное время сна, вплоть до полдюжины микросекунд.

Так что, возможно, OP хочет что-то, что будет грубо работать большую часть времени в системе на холостом ходу, и иметь возможность запрашивать планирование микросекунд! На самом деле я бы тоже хотел этого в Windows.

Также Sleep (0) звучит как boost :: thread :: yield (), терминология которого более ясна.

Интересно, имеют ли блокировки с Boost более высокую точность. Потому что тогда вы можете просто заблокировать мьютекс, который никто никогда не выпускает, и, когда истечет время ожидания, продолжить ... Таймауты устанавливаются с помощью boost :: system_time + boost :: milliseconds & cie (xtime устарел).

person Lightness1024    schedule 11.05.2012

Если ваша цель - «подождать очень короткий промежуток времени», потому что вы выполняете спин-ожидание, то уровни ожидания, которые вы можете выполнить, увеличиваются.

void SpinOnce(ref Int32 spin)
{
   /*
      SpinOnce is called each time we need to wait. 
      But the action it takes depends on how many times we've been spinning:

      1..12 spins: spin 2..4096 cycles
      12..32: call SwitchToThread (allow another thread ready to go on time core to execute)
      over 32 spins: Sleep(0) (give up the remainder of our timeslice to any other thread ready to run, also allows APC and I/O callbacks)
   */
   spin += 1;

   if (spin > 32)
      Sleep(0); //give up the remainder of our timeslice
   else if (spin > 12)
      SwitchTothread(); //allow another thread on our CPU to have the remainder of our timeslice
   else
   {
      int loops = (1 << spin); //1..12 ==> 2..4096
      while (loops > 0)
         loops -= 1;
   }
}

Поэтому, если ваша цель на самом деле подождать совсем немного, вы можете использовать что-то вроде:

int spin = 0;
while (!TryAcquireLock()) 
{ 
   SpinOne(ref spin);
}

Достоинство здесь в том, что мы каждый раз ждем дольше и в конечном итоге полностью засыпаем.

person Ian Boyd    schedule 22.04.2017

Попробуйте boost :: xtime и timed_wait ()

имеет наносекундную точность.

person theschmitzer    schedule 17.09.2008
comment
Вы путаете точность с точностью. - person IInspectable; 07.07.2016

Просто используйте Sleep (0). 0 явно меньше миллисекунды. Звучит смешно, но я серьезно. Sleep (0) сообщает Windows, что вам сейчас нечего делать, но вы действительно хотите, чтобы вас пересмотрели, как только планировщик снова запустится. И поскольку очевидно, что выполнение потока невозможно запланировать до запуска самого планировщика, это самая короткая возможная задержка.

Обратите внимание, что вы можете передать в usleep микросекундное число, но это не значит, что usleep (__ int64 t) {Sleep (t / 1000); } - нет никаких гарантий, что вы действительно спите в этот период.

person MSalters    schedule 18.09.2008
comment
Я думаю, что если вы действительно попробуете это, вы обнаружите, что Sleep (0) обычно спит 10-15 мс в зависимости от вашего оборудования и загрузки системы. - person Dave Moore; 19.09.2008
comment
Из MSDN: нулевое значение заставляет поток передавать оставшуюся часть своего временного интервала любому другому потоку с таким же приоритетом, который готов к запуску. Если нет других потоков с равным приоритетом, готовых к запуску, функция немедленно возвращается, и поток продолжает выполнение. - person Ferruccio; 24.09.2008
comment
Последняя часть ответа неверна. Если вы разделите int на 1000, тогда любое значение ниже 1000 будет установлено в 0. Таким образом, ваша функция usleep просто вызовет Sleep (0) для любого значения меньше миллисекунды. И, как сказал @Ferruccio, Sleep (0) не спит менее миллисекунды, здесь это опасность. - person xryl669; 10.01.2017

Функция сна, которая длится меньше миллисекунды, может быть

Я обнаружил, что у меня работает sleep (0). В системе с почти 0% загрузкой процессора в диспетчере задач я написал простую консольную программу, и функция sleep (0) спала в течение последовательных 1-3 микросекунд, что намного меньше миллисекунды.

Но из приведенных выше ответов в этом потоке я знаю, что количество спящих сна (0) может варьироваться гораздо более дико, чем это в системах с большой загрузкой процессора.

Но как я понимаю, функцию сна не стоит использовать как таймер. Его следует использовать для того, чтобы программа использовала как можно меньше ресурсов процессора и выполнялась как можно чаще. Для моих целей, таких как перемещение снаряда по экрану в видеоигре, намного быстрее, чем один пиксель в миллисекунду, я думаю, что режим сна (0) работает.

Вы просто должны убедиться, что интервал сна намного меньше, чем наибольшее время, в течение которого он будет спать. Вы не используете спящий режим в качестве таймера, а просто для того, чтобы игра использовала минимально возможный процент процессора. Вы бы использовали отдельную функцию, которая не имеет никакого отношения к сну, чтобы узнать, когда прошло определенное количество времени, а затем переместить снаряд на один пиксель по экрану, скажем, за 1/10 миллисекунды или 100 микросекунд. .

Псевдокод будет выглядеть примерно так.

while (timer1 < 100 microseconds) {
sleep(0);
}

if (timer2 >=100 microseconds) {
move projectile one pixel
}

//Rest of code in iteration here

Я знаю, что ответ может не работать для сложных задач или программ, но может работать для некоторых или многих программ.

person rauprog    schedule 31.10.2015
comment
В играх вы не должны полагаться на тайминги кадров, вместо этого используйте скорость * тайминг. Так у вас не возникнет проблем, если компьютер будет перегружен. - person Cem Kalyoncu; 29.06.2016
comment
@CemKalyoncu = или если тот же код будет запущен намного позже на значительно лучшем оборудовании. Я написал несколько старых рото-зумеров, систем частиц и различных эффектов для 386 и 486. Я уверен, вы можете представить, насколько непристойными они были при запуске на i3 (в одном случае от 20 кадров в секунду до более 700! !!) - person enhzflep; 22.10.2016

В Windows использование select заставляет вас включать Winsock, которая должна быть инициализирована в вашем приложении следующим образом:

WORD wVersionRequested = MAKEWORD(1,0);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);

И тогда выбор не позволит вам вызываться без какого-либо сокета, поэтому вам нужно сделать еще немного, чтобы создать метод микросна:

int usleep(long usec)
{
    struct timeval tv;
    fd_set dummy;
    SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    FD_ZERO(&dummy);
    FD_SET(s, &dummy);
    tv.tv_sec = usec/1000000L;
    tv.tv_usec = usec%1000000L;
    return select(0, 0, 0, &dummy, &tv);
}

Все эти созданные методы usleep возвращают ноль в случае успеха и ненулевое значение в случае ошибок.

person Jorge Ferreira    schedule 17.09.2008
comment
Эта имплантация Sleep () пропускает сокет каждый раз, когда он вызывается! - person Jeremy Friesner; 25.03.2015
comment
Этот метод «спит» около 15 миллисекунд, даже если запрошен только 1 микросекундный спящий режим. - person Serge Rogatch; 18.09.2015
comment
Вам не нужно создавать сокет для вызова select (). Пожалуйста, удалите этот ответ. - person craig65535; 27.01.2016
comment
Это копирует реализацию, но не семантику. Вы не можете реализовать задержку с продолжительностью ниже, чем частота таймера. Извините, это бесполезно и вводит в заблуждение. По крайней мере, отмените выбор этого ответа как принятого. Конечно, поскольку вы никогда не решались задать вопрос, любой ответ был бы одинаково хорош, если бы он никогда не вводил в заблуждение. - person IInspectable; 07.07.2016