Вопрос

Я уже узнал с другим вопросом, что Windows/Mingw не предоставляют альтернативы Nanosleep () и Setitimer () устаревшему usleep (). Но моя цель - исправить все предупреждения, которые дает мне CPPCHECK, включая предупреждения в стиле использования ().

Итак, есть ли обходной путь, чтобы каким -то образом избежать использования () в Windows без Использование Cygwin или установка множества новых зависимостей/библиотек? Спасибо.

Это было полезно?

Решение

usleep() работает с микросекундами. В Windows для получения микросекундной предыстории вы должны использовать QueryperformanceCounter () Winapi функция. Здесь Вы можете найти, как получить это предложение, используя его.

Другие советы

Я использовал этот код из (первоначально от здесь):

#include <windows.h>

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, &ft, 0, NULL, NULL, 0); 
    WaitForSingleObject(timer, INFINITE); 
    CloseHandle(timer); 
}

Обратите внимание, что SetWaitableTimer() использует "100 наносекундных интервалов ... положительные значения указывают на абсолютное время. ... отрицательные значения указывают на относительное время."И это"Фактическая точность таймера зависит от возможности вашего оборудования."

Если у вас есть компилятор C ++ 11, то вы можете использовать это портативная версия:

#include <chrono>
#include <thread>
...
std::this_thread::sleep_for(std::chrono::microseconds(usec));

Престижность Говарду Хиннанту, который разработал удивительный <chrono> Библиотека (и чей ответ ниже заслуживает больше любви.)

Если у вас нет C ++ 11, но у вас есть повышение, то вы можете сделать это вместо:

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
...
boost::this_thread::sleep(boost::posix_time::microseconds(usec));

Новый ответ на старый вопрос:

Обоснование нового ответа: инструменты / OSS были обновлены так, что сейчас есть лучший выбор, чем когда был задан вопрос.

C ++ 11 <chrono> а также <thread> Заголовки 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 (Modulo The Chrono-Literals). Я не уверен в более ранних версиях Vs.

Миллисекундный режим Sleep() Функция хорошо описана и хорошо понятна. Это не делает ничего непредсказуемого. Иногда функция обвиняется в выполнении непредсказуемой, то есть возвращение до истечения срока действия задержки. Мне нужно сказать, что это неправильно. Тщательное расследование подтвердит, что его поведение абсолютно предсказуемо. Единственная проблема заключается в том, что об этом есть что прочитать, и большая часть этого детской. Также часто говорят, что Windows это не ОС в реальном времени. Но такие комментарии ничего не вносят вклад, более того, такие комментарии используются, чтобы скрыть отсутствие знаний. Это меня немного злится, что даже Microsoft не замечает этого и обеспечивает лучшую документацию.

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

Таким образом, в целом настоящий сон можно выполнить легко и безопасно вплоть до периода прерывания систем. Когда дело доходит до сна короче, чем требуется период прерывания. Источник с более высоким разрешением необходимо использовать в Oder, чтобы вращаться в течение более коротких периодов времени. Самым распространенным источником для этого является счетчик производительности. QueryPerformanceCounter(*arg) доставляет увеличение *arg. QueryPerformanceFrequency(*arg) обеспечивает частоту, с которой увеличивается счетчик производительности. Обычно это находится в режиме MHZ и варьируется, в зависимости от базового оборудования. Частота в диапазоне MHZ обеспечивает микросекундное разрешение. Таким образом, что -то из высокого разрешения может быть использовано, чтобы ждать желаемого периода времени, чтобы истечь. Тем не менее, точность этого должна быть внимательно изучать: ОС возвращает частоту счетчика производительности как постоянную. Это не правильно! Поскольку частота генерируется физическим устройством, всегда есть смещение, и она также не постоянная. У него тепловой дрейф. Более современные системы имеют меньше дрейфа. Но если тепловой дрейф составляет всего 1PLM, ошибка будет 1ус/с. Смещение может быть легко составлять несколько 100. Смещение 100 в 1 МГц соответствует 100US/с.

Если поток будет ждать какого -либо времени в высоком разрешении, он должен установить поток обслуживания. Оба потока должны поделиться именованным событием. Сервисная нить должна спать до 1 периода прерывания перед желаемой задержкой сна, а затем вращается на счетчик производительности для оставшейся микросекундной. Когда потока службы достигает последнего времени, он установил именованное событие и заканчивается. Призывник просыпается, потому что он ждал именованного события с помощью функции ожидания.

Резюме:

  • Сон хорошо изучен, но плохо задокументирован.
  • Сервисная нить может имитировать сна при высоком разрешении.
  • Такая сервисная нить coulb будет заполнена как общеобразовательная служба.
  • Точность счетчика производительности следует внимательно изучить. Требуется калибровка.

Более подробную информацию можно найти в Windows TimeStamp Project

Это зависит от того, какую деталь вам нужна. Если вы говорите Milliseconds, то функция сна win32 выполнит работу - см. http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx. Анкет Если вы говорите о микросекундах, то нет простого способа сделать это, и вам повезло получить такое разрешение таймера в Windows (которая не является RTO) или на Linux, прийти к этому.

я нашел этот пост об этом. Анкет Оно использует QueryPerformanceCounter. Анкет Опубликована функция:

#include <windows.h>

void uSleep(int waitTime) {
    __int64 time1 = 0, time2 = 0, freq = 0;

    QueryPerformanceCounter((LARGE_INTEGER *) &time1);
    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);

    do {
        QueryPerformanceCounter((LARGE_INTEGER *) &time2);
    } while((time2-time1) < waitTime);
}

Я надеюсь, что это немного поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top