Я уже выяснил с другим вопросом, что Windows / MingW не предоставляет альтернативы nanosleep() и setitimer() для устаревшего usleep(). Но моя цель-исправить все предупреждения, которые cppcheck дает мне, включая предупреждения стиля usleep ().
Так, есть ли обходной путь, чтобы как-то избежать usleep() в Windows без использование cygwin или установка нагрузок новых зависимостей/библиотек? Спасибо.
автор: Kara
6 ответов
usleep() работает с МКС. В windows для получения микросекундной прецессии вы должны использовать QueryPerformanceCounter() функция winapi. здесь вы можете найти, как сделать, что precesion, используя его.
автор: Mihran Hovsepyan
я использовал этот код (родом из здесь):
#include void usleep(__int64 usec) < HANDLE timer; LARGE_INTEGER ft; ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time timer = CreateWaitableTimer(NULL, TRUE, NULL); SetWaitableTimer(timer, WaitForSingleObject(timer, INFINITE); CloseHandle(timer); >
отметим, что SetWaitableTimer() использует «100 наносекундных интервалов . Положительные значения указывают на абсолютное время. . Отрицательные значения указывают на относительное время.» и «фактическая точность таймера зависит от возможностей вашего оборудования.»
Что это значит?🙈
если у вас есть компилятор C++11, вы можете использовать этой портативное версия:
#include #include . std::this_thread::sleep_for(std::chrono::microseconds(usec));
престижность объектов Ховард, который создал удивительный библиотека (и ответ на который ниже заслуживает больше любви.)
если у вас нет C++11, но у вас есть boost, то вы можете сделать этой вместо:
#include #include . boost::this_thread::sleep(boost::posix_time::microseconds(usec));
автор: Adi Shavit
режим миллисекунду Sleep() функция хорошо описана и хорошо понята. Он не делает ничего непредсказуемого. Иногда функцию обвиняют в непредсказуемости, т. е. в возврате до истечения срока задержки. Я должен сказать, что это неправильно.
Тщательное расследование подтвердит, что его поведение абсолютно предсказуемо. Единственная проблема что существует много читала об этом и по-детски. Также часто говорят, что windows это не ОС реального времени. Но такие комментарии ничего не дают, более того такие комментарии используются для того, чтобы скрыть отсутствие знаний. Это меня злит, что даже microsoft замечает это и предоставляет лучшую документацию.
однако, не преувеличивая этот маленький ответ: функция sleep() точна, когда используется надлежащим образом и когда знает ее характеристики. Особое внимание следует уделить сну(0). Это очень мощный инструмент, особенно при использовании вместе с Процесс класс приоритета, приоритет потока, настройки мультимедийного таймера и процессора маски.
так вообще истинный сон можно выполнить легко и безопасно вниз к периоду прерывания систем. Когда дело доходит до спит короче, чем период прерывания спиннинг требуется. Источник времени с более высоким разрешением должен использоваться в oder для вращения в течение более коротких периодов времени.
SKYRIM — А ЧТО ЭТО ТАКОЕ? (ДЕВУШКА ПРОБУЕТ СКАЙРИМ)
Наиболее распространенным источником для этого является счетчик производительности. QueryPerformanceCounter(*arg) обеспечивает увеличение * arg. QueryPerformanceFrequency(*arg) доставляет частота, с которой счетчик производительности увеличивается. Это, как правило, в режиме МГц и варьируется в зависимости от базового оборудования. Частота в диапазоне Мгц обеспечивает микросекундное разрешение.
Таким образом, что-то с высоким разрешением можно использовать для ожидания желаемого промежутка времени. Однако точность этого следует тщательно изучить: ОС возвращает частоту счетчика производительности как константу. Это неправильно! Поскольку частота генерируется физическим устройством, там всегда смещение и оно также не a постоянный. Он имеет термальный дрейф.
Более современные системы имеют меньший дрейф. Но если тепловой дрейф составляет всего 1ppm, ошибка будет 1us / s. Смещение может легко быть несколько 100. Смещение 100 в 1MHz соответствует 100us / s.
если поток должен ждать в любое время с высоким разрешением, он должен установить служебный поток. Оба потока должны совместно использовать именованное событие. Поток обслуживания будет спать до 1 периода прерывания перед пожеланным сном задержка, а затем вращение на счетчике производительности в течение оставшейся микросекунды. Когда поток службы достигает последнего времени, он устанавливает именованное событие и завершается. Вызывающий поток проснется, потому что он ждал именованного события с помощью функции wait.
- сон хорошо понимается, но плохо документируется.
- служебный поток может имитировать спящие с высоким разрешением.
- такой поток обслуживания coulb быть esablished как общесистемный сервис.
- точность счетчика производительности следует внимательно изучить. Необходима калибровка.
более подробную информацию можно найти в Проект Метки Времени Windows
автор: Arno
новый ответ на старый вопрос:
обоснование нового ответа: инструменты / OSs были обновлены таким образом, что теперь есть лучший выбор, чем когда вопрос был первоначально задан.
C++11 и заголовки std находятся в наборе инструментов VS уже несколько лет. Используя эти заголовки, это лучше всего закодировано в C++11 как:
std::this_thread::sleep_for(std::chrono::microseconds(123));
Я использую микросекунды только в качестве примера продолжительности. Вы можете использовать любую продолжительность чтобы быть удобным:
std::this_thread::sleep_for(std::chrono::minutes(2));
С C++14 и некоторыми директивами использования это можно написать немного компактнее:
using namespace std::literals; std::this_thread::sleep_for(2min);
std::this_thread::sleep_for(123us);
это определенно работает на VS-2013 (по модулю хроно-литералов). Я не уверен в более ранних версиях VS.
автор: Howard Hinnant
Это зависит от того, какая детализация вам нужна. Если вы говорите миллисекунды, то функция Win32 Sleep выполнит эту работу-см. http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx. Если вы говорите микросекунды, то нет простого способа сделать это, и Вам ПОВЕЗЕТ, чтобы получить такое разрешение таймера на Windows (которая не является RTOS) или на Linux, прийти к этому.
автор: Neil Butterworth
нашел это сообщение в блоге об этом. Он использует QueryPerformanceCounter . Функция опубликована:
#include void uSleep(int waitTime) < __int64 time1 = 0, time2 = 0, freq = 0; QueryPerformanceCounter((LARGE_INTEGER *) QueryPerformanceFrequency((LARGE_INTEGER *) do < QueryPerformanceCounter((LARGE_INTEGER *) >while((time2-time1)
надеюсь, это немного поможет.
Источник: askdev.ru
Usleep skyrim что это такое
Функция usleep() приостанавливает выполнение процесса на usec микросекунд. Остановка может продлиться несколько больше из-за системной активности или из-за того, что для осуществления вызова требуется определенное время.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
Функция ничего не возвращает (BSD). Или возвращается 0 при номальном завершении работы и -1 при ошибках (SUSv2).
СООБЩЕНИЕ ОБ ОШИБКАХ
EINTR Прервано сигналом. EINVAL usec больше, чем 1000000. (В тех системах, где это условие вызывает ошибку.)
СООТВЕТСТВИЕ СТАНДАРТАМ
Стандарт BSD 4.3. В версиях SUSv2 возвращается целое число, и это тот прототип, что используется в glibc 2.2.2. В SUSv2 указано, что возвращаться может только ошибка EINVAL.
ЗАМЕЧАНИЯ
Тип useconds_t является беззнаковым целым типом, способным определять целые числа в диапазоне [0,1000000]. Программы будут иметь более высокий уровень переносимости на другие ОС, если они никогда не будут явно упоминать этот тип. Используйте
#include unistd.h> . unsigned int usecs; . usleep(usecs);
Этот тип определен включенным с помощью но glibc определяет его только когда _XOPEN_SOURCE имеет значение не меньше 500, или если определены одновременно и _XOPEN_SOURCE, и _XOPEN_SOURCE_EXTENDED.
Взаимодействие этой функции с сигналом SIGALRM и другими функциями таймера, такими как alarm (), sleep (), nanosleep (), setitimer (), timer_create (), timer_delete (), timer_getoverrun (), timer_gettime (), timer_settime (), ualarm () неопределено.
Эта функция устарела. Используйте вместо нее функции nanosleep (2) или setitimer (2).
Источник: www.opennet.ru
Влияние usleep (0) в C++ на Linux
на документация для usleep гласит, что вызов usleep(0) не имеет никакого эффекта. Однако в моей системе (RHEL 5.2), запускающей небольшие фрагменты кода C++ ниже, я нахожу, что он на самом деле имеет тот же эффект, что и usleep(1) . Можно ли этого ожидать, и если да, то почему существует несоответствие между документацией и тем, что я вижу в реальной жизни?
выставки А
#include int main() < for( int i = 0; i < 10000; i++ ) < usleep(1); >>
$ time ./test real 0m10.124s user 0m0.001s sys 0m0.000s
Экспонат B
#include int main() < for( int i = 0; i < 10000; i++ ) < usleep(1); usleep(0); >>
$ time ./test real 0m20.770s user 0m0.002s sys 0m0.001s
автор: Dunnie
7 ответов
технически это не должно иметь никакого эффекта. Но вы должны помнить, что переданное значение используется как минимум, а не абсолют, поэтому система может использовать наименьший возможный интервал вместо этого.
автор: Ignacio Vazquez-Abrams
Я просто хотел указать на команду времени, используемую здесь. Вы должны использовать /usr/bin/time вместо time команда, если вы хотите проверить память программы, cpu, time stat. Когда вы вызываете время без полного пути, тогда вызывается встроенная команда времени. Посмотрите на разницу.
без полного пути:
# time -v ./a.out -bash: -v: command not found real 0m0.001s user 0m0.000s sys 0m0.001s
полный путь:
# /usr/bin/time -v ./a.out Command being timed: «./a.out» User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 0% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:10.87 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 0 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 220 Voluntary context switches: 10001 Involuntary context switches: 1 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
использовать man time на /usr/bin/time руководство и использовать help time для встроенных в времени.
автор: niloydebnath
Мне нужно было бы посмотреть на источник, чтобы убедиться, но я предполагаю, что это не совсем «нет эффекта», но это, вероятно, все еще меньше, чем usleep(1) — все еще накладные расходы вызова функции, которые могут быть измерены в узком цикле, даже если вызов библиотеки просто проверяет свои аргументы и немедленно возвращается, избегая более обычного процесса настройки таймера/обратного вызова и вызова планировщика.
автор: twalberg
эта документация вернулась с 1997 года, не уверен, что она применима к текущему RHEL5, моя справочная страница Redhat dev systems для usleep не указывает, что время сна 0 не имеет никакого эффекта.
параметр вы передаете-это минимальное время для сна. Нет никакой гарантии, что поток проснется ровно через указанное время. Учитывая конкретную динамику планировщика, это может привести к более длительным задержкам, чем ожидалось.
автор: Gearoid Murphy
usleep() и sleep() переводится как nanosleep() система звонков. Попробуй!—4—> ваша программа, и Вы ее увидите. От nanosleep() руководство:
nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed, or the delivery of a signal that triggers the invocation of a handler in the calling thread or that terminates the process.
поэтому я думаю, что ulseep (0) создаст прерывание и контекстный переключатель.
автор: Peng Zhang
Это также зависит от того, реализован ли udelay как цикл занятости для коротких длительностей.
автор: happycube
по моему опыту, это имеет один эффект: это вызов прерывания.
Это хорошо, чтобы освободить процессор для наименьшего количества времени в многопоточном программировании.
Источник: askdev.ru