2

私はいくつかのものを作る別のスレッドで私のプロジェクトを持っています。

それはすべて大丈夫ですが、たとえば20msごとに呼び出される関数があればいいのですが、関数に費やされる時間を考慮して...もっとよく説明しようとしています...関数を呼び出し、関数が終了するのに6msを費やしました。スレッドが14ms(20-6)スリープすることを望みます。次に呼び出されるとき、関数は12msを費やしたので、スリープはわずか8msになります。これを行うにはどうすればよいですか?これが私のコードです:

// thread constructor
DWORD dwThreadId, dwThrdParam = 1;  
HANDLE thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)workerFunc, &dwThrdParam, 0, &dwThreadId );

// thread function
DWORD WINAPI workerFunc( LPDWORD lpdwParam )
{
    while( true )
    {
        myFunction( );
        Sleep( ??? );
    }
    return 0;
}

ありがとう!

4

4 に答える 4

2

これはどうですか:

clock_t start, end;
while( true )
{
    start = clock();
    myFunction( );
    end = clock();
    Sleep(20-(end-start)*CLOCKS_PER_SEC/1000.0);
}
于 2011-07-18T11:35:54.813 に答える
2

簡単な方法は、スレッドを一定時間スリープ状態にすることです。

void periodic_function()
{
  /* function body */

  timestamp = get_time(); // pseudo-function
  remaining_sleep_time = std::min(0, 20 - (timestamp - last_timestamp));
  last_timestamp = timestamp;
  milli_sleep_callback(remaining_sleep_time, periodic_function);
}

適切な定常時計機能get_time()とスリープ機能が必要です -<chrono>または<tr1/chrono>ヘッダーを試してください。この例では、(boost.ASIO のような) タイマー コールバックがあると想定していますが、無限ループなどを作成することもできます。

この関数は、関数本体が 20 ミリ秒を超えない場合に機能しますが、関数がそれより長くかかる場合はすばやく追いつきます。グローバルな 20 ミリ秒のリズムに同期させたい場合は、別のグローバル ステップ カウンターなどを追加する必要があります。

于 2011-07-18T11:41:46.220 に答える
1

を呼び出す前と呼び出した後にGetTickCountを使用します。その差が、 で費やされた時間になります。この時間には、OS のスケジューリングのためにプロセスが費やした時間が含まれていることに注意してください。myFuncmyFuncmyFunc

于 2011-07-18T11:34:37.513 に答える
0

精度が必要な場合はNtSetTimerResolution、プログラムの起動時に使用してタイマーの解像度を設定します。はい、文書化されていない機能ですが、うまく機能します。また、タイマーの解像度を知るために使用することもできますNtQueryTimerResolution(設定する前と新しい解像度を確実に設定した後)。

これらの関数のアドレスは、ヘッダーまたは LIB ファイルで宣言されていないため、GetProcAddressfromを使用して動的に取得する必要があります。NTDLL.DLL

この方法でタイマーの解像度を設定するとSleep、Windows タイマー、現在の時刻を返す関数などに影響します。

于 2011-08-20T12:09:11.120 に答える