c ++、usleep()は時代遅れで、Windows/Mingwの回避策ですか?
質問
私はすでに、Windows/MingwがNanos Sleep()とSetitimer()の代替品を廃止したUSELEEP()を提供していないことをすでに知りました。しかし、私の目標は、cppcheckが私に与えてくれるすべての警告を修正することです。
したがって、WindowsでUsleep()を避けるための回避策はありますか それなし Cygwinを使用するか、多数の新しい依存関係/ライブラリをインストールしますか?ありがとう。
解決
usleep()
マイクロ秒で動作します。 Microsecond Precesionを取得するための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(Chrono-Literalsのモジュロ)で機能します。 Vsの以前のバージョンについてはわかりません。
のミリ秒のレジーム Sleep()
機能はよく説明されており、よく理解されています。予測不可能なことは何もしません。場合によっては、この機能が予測不可能であると非難されることがあります。つまり、遅延が期限切れになる前に戻ってきます。これは間違っていると言う必要があります。慎重な調査では、その動作が絶対に予測可能であることが確認されます。唯一の問題は、それについて読むべきことがたくさんあり、そのほとんどが子供であることです。また、WindowsはリアルタイムOSではないとよく言われています。しかし、そのようなコメントは何も貢献しません。さらに、そのようなコメントは知識の欠如を隠すために使用されます。 Microsoftがこれに気づかず、より良いドキュメントを提供していないことは、私を怒らせます。
ただし、この小さな答えを誇張することなく:睡眠()関数は、適切な方法で使用され、その特性を知っている場合、正確です。睡眠に特に注意を払う必要があります(0)。これは非常に強力なツールであり、プロセス優先度クラス、スレッド優先度、マルチメディアタイマー設定、プロセッサアフィニティマスクとともに使用する場合の特性です。
したがって、一般的に、真の睡眠は、システムの割り込み期間まで容易に安全に実行できます。睡眠に関しては、割り込み期間よりも短く眠ることが必要です。より高い解像度の時間ソースを使用して、時間内に短い期間スピンする必要があります。これの最も一般的なソースは、パフォーマンスカウンターです。 QueryPerformanceCounter(*arg)
増分 *argを提供します。 QueryPerformanceFrequency(*arg)
パフォーマンスが刻まれている頻度を提供します。これは通常、MHZレジームであり、基礎となるハードウェアによって異なります。 MHz範囲の周波数は、マイクロ秒解像度を提供します。このようにして、高解像度の何かを使用して、望ましい時間範囲が期限切れになるのを待つことができます。ただし、これの精度を慎重に検討する必要があります。OSは、パフォーマンスカウンター周波数を定数として返します。これは間違っています!周波数は物理デバイスであるため、常にオフセットがあり、定数もありません。サーマルドリフトがあります。より近代的なシステムのドリフトは少なくなっています。ただし、サーマルドリフトがわずか1ppmの場合、エラーは1us/sになります。オフセットは容易に数00になります。1MHzで100のオフセットは100US/sに対応します。
スレッドが高解像度でいつでも待つ場合、サービススレッドを確立するものとします。両方のスレッドは、名前付きイベントを共有するものとします。サービススレッドは、目的の睡眠遅延より1回の割り込み期間までスリープし、その後、残りのマイクロ秒のパフォーマンスカウンターでスピンする必要があります。サービススレッドが最終時間に達すると、名前付きイベントを設定して終了します。通話スレッドは、待機機能によって指名されたイベントを待っていたため、目覚めます。
概要:
- 睡眠はよく理解されていますが、文書化が不十分です。
- サービススレッドは、高解像度で眠ることができます。
- このようなサービススレッドCoulbは、システムワイドサービスとしてexablisedされます。
- パフォーマンスカウンターの精度は、慎重に検討することです。キャリブレーションが必要です。
より詳細な情報は、にあります Windowsタイムスタンププロジェクト
それはあなたが必要とする粒度によって異なります。ミリ秒を話している場合、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);
}
これが少し役立つことを願っています。