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

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

53
задан doc 15 February 2015 в 11:59
поделиться

12 ответов

В 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 нуль возврата методов когда успешный и ненулевой для ошибок.

-3
ответ дан rene 7 November 2019 в 08:15
поделиться

Это указывает на неверное толкование функций сна. Параметр, который Вы передаете, минимум время для сна. Нет никакой гарантии, что поток проснется после точно определенное время. На самом деле потоки не 'просыпаются' вообще, но скорее выбраны для выполнения планировщиком. Планировщик мог бы принять решение ожидать намного дольше, чем требуемая продолжительность сна для активации потока, особенно если другой поток все еще активен в тот момент.

89
ответ дан Joel Coehoorn 7 November 2019 в 08:15
поделиться

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

Примечание, которое Вы можете передать в числе микросекунды своему usleep, но так освобождаете usleep (__ int64 t) {Сон (t/1000);} - никакие гарантии к фактическому сну того периода.

0
ответ дан Peter Mortensen 7 November 2019 в 08:15
поделиться

Повышение попытки:: xtime и timed_wait ()

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

0
ответ дан theschmitzer 7 November 2019 в 08:15
поделиться

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

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

4
ответ дан Rob Walker 7 November 2019 в 08:15
поделиться

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

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

5
ответ дан mbyrne215 7 November 2019 в 08:15
поделиться

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

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

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

при поиске чего-то точного необходимо пойти: 1) В пространстве ядра (как драйверы) 2) Выбирают RTOS.

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

6
ответ дан xryl669 7 November 2019 в 08:15
поделиться

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

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

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

10
ответ дан darron 7 November 2019 в 08:15
поделиться

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

29
ответ дан Joe Schneider 7 November 2019 в 08:15
поделиться

Как Joel говорит, Вы не можете обоснованно 'спать' (т.е. оставить свой запланированный ЦП) в течение таких коротких периодов. Если Вы хотите задержаться в течение некоторого короткого времени, то необходимо вращаться, неоднократно проверяя соответственно таймер с высоким разрешением (например, 'таймер производительности') и надеясь, что что-то вроде высокого приоритета не покупает право на Вас так или иначе.

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

46
ответ дан Will Dean 7 November 2019 в 08:15
поделиться

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

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

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

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

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

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

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

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

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

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

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

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

2
ответ дан 7 November 2019 в 08:15
поделиться

На самом деле использование этой функции 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;
}
2
ответ дан 7 November 2019 в 08:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: