#pragma twice

KAB-studio > プログラミング > #pragma twice > 277 Version 14.10 タイマーを使おう!

#pragma twice 277 Version 14.10 タイマーを使おう!

前のページへ 表紙・目次へ 次のページへ

 Version 14.10
タイマーを使おう!

「同期オブジェクト3つめはタイマーです」

タイマー ( Waitable timer )

「タイマーも仕組みそのものは難しくありません」
『バトンとかそんな感じ?』
「そういうこと。同じように走ることを例に取ると」

・一定時間毎に走り出す

「のがタイマーかな」
『?』
「選手A、B、Cがいる時に、まずAが走って、その1分後にBが走って、
そのさらに1分後にCが走る」
『ハンデみたいな感じ?』
「そんな感じ。まずはいつも通り、プログラムを見てもらおうか」

namespace B1
{

HANDLE g_hTimer = NULL;
const char *const TIMER_NAME= "ProcessesTimer";

// タイマーを作成します。
void Create()
{
    g_hTimer = CreateWaitableTimer( NULL, FALSE, TIMER_NAME );
    TRACE( "%x\n", g_hTimer );
}

// タイマーを取得します。
void Open()
{
    g_hTimer = OpenWaitableTimer( TIMER_ALL_ACCESS, FALSE, TIMER_NAME );
    TRACE( "%x\n", g_hTimer );
}

// タイマーをセットします。
void Set()
{
    // タイマーを開始するまでの100ナノ秒数。
    const int DUE_NSEC = -5 * 1000 * 1000 * 10;
    LARGE_INTEGER largeInteger;
    largeInteger.QuadPart = DUE_NSEC;
    // タイマーの間隔のミリ秒数。
    const int INTERVAL_MSEC = 15000;
    BOOL b 
        = SetWaitableTimer
            ( g_hTimer
            , &largeInteger
            , INTERVAL_MSEC
            , NULL
            , NULL
            , FALSE
            );
    TRACE( "%d\n", b );
}

// タイマーを監視して待機状態に入ります。
void Wait()
{
    TRACE( "待機開始。\n" );
    DWORD dwResult = WaitForSingleObject( g_hTimer, 120000 );

    if( dwResult == WAIT_TIMEOUT )
    {
        TRACE( "タイムアウト。\n" );
    }
    else
    {
        TRACE( "待機終了。\n" );
    }
}

// タイマーをキャンセルします。
void Cancel()
{
    LONG lCount = 0;
    BOOL b = CancelWaitableTimer( g_hTimer );
    TRACE( "%d\n", b );
}

// タイマーを削除します。
void Close()
{
    CloseHandle( g_hTimer );
}

}

「前回と関数の数と名前が違うから注意して」
『 Set() が追加されて…… Release() が Cancel() になってる?』
「そうです。このあたりはタイマーが他の同期オブジェクトと違う点かな。
じゃあ、ひとつずつ見ていこうか」

HANDLE g_hTimer = NULL;
const char *const TIMER_NAME= "ProcessesTimer";

『これはいつもと同じ、ハンドルと名前ね』
「この辺はどの同期オブジェクトも同じだから。次も同じ」

// タイマーを作成します。
void Create()
{
    g_hTimer = CreateWaitableTimer( NULL, FALSE, TIMER_NAME );
    TRACE( "%x\n", g_hTimer );
}

「これはタイマーを作る関数。引数も他と同じ」
『じゃ、次』

// タイマーを取得します。
void Open()
{
    g_hTimer = OpenWaitableTimer( TIMER_ALL_ACCESS, FALSE, TIMER_NAME );
    TRACE( "%x\n", g_hTimer );
}

「これも同じ、元々作ってあるタイマーを取得します」
『 TIMER_NAME と同じ名前のタイマーを取得するんだね』
「そういうこと。では次、これはちょっとややこしいです」
『追加された関数だね』

// タイマーをセットします。
void Set()
{
    // タイマーを開始するまでの100ナノ秒数。
    const int DUE_NSEC = -5 * 1000 * 1000 * 10;
    LARGE_INTEGER largeInteger;
    largeInteger.QuadPart = DUE_NSEC;
    // タイマーの間隔のミリ秒数。
    const int INTERVAL_MSEC = 15000;
    BOOL b 
        = SetWaitableTimer
            ( g_hTimer
            , &largeInteger
            , INTERVAL_MSEC
            , NULL
            , NULL
            , FALSE
            );
    TRACE( "%d\n", b );
}

「この関数は、タイマーを実際にセットします」
『時間セットしてオンにする、みたいな?』
「そういうこと。 OpenWaitableTimer() は作るだけだから、この 
SetWaitableTimer() でセットしなきゃいけないんです」
『でも数字多くてよくわかんない……』
「使う数はふたつ。まずひとつめは、タイマーが一番最初にオンになるまで
の時間」

    // タイマーを開始するまでの100ナノ秒数。
    const int DUE_NSEC = -5 * 1000 * 1000 * 10;

『ナノ秒……?』
「1秒の1000分の1がミリ秒、ミリ秒の1000分の1がマイクロ秒、
マイクロ秒の1000分の1がナノ秒。あ、この単位は100ナノ秒だか
ら、マイクロ秒の10分の1が100ナノ秒」
『すごく小さな数……』
「でもナノって数はあまり気にしなくていいかも。この例では 5 だから
5秒後ってこと」
『ん? マイナス付いてるけど』
「実はこの第2引数にはふたつの使い道があるんです」

・正の数:1601/01/01 00:00:00 からののべ時間
・負の数:呼び出した瞬間からののべ秒

「つまり、正の時間を使えば〈2004年1月1日0時0分0秒から〉とい
うふうにきっちりとした時間からタイマーを開始できるんです」
『そっちはタイマーっていうよりアラームだね』
「どっちの場合でも、 LARGE_INTEGER っていう構造体に入れて渡します」

    LARGE_INTEGER largeInteger;
    largeInteger.QuadPart = DUE_NSEC;

「この構造体は 64 ビットサイズの整数値を入れられます」
『 64 ビットっていうと…… int が 32 ビットだからその倍だね』
「 int の最大値より、 2 の 32 乗大きい数を入れられるってことだから」
『うわすご!』
「100ナノ秒だし、正の数の時には大きな数になるからね……で、今のが
スタートするまでの時間。次はタイマーの間隔」

    // タイマーの間隔のミリ秒数。
    const int INTERVAL_MSEC = 15000;

「タイマーは一定時間毎にオンになるから、その間隔」
『これはミリ秒数だから……15秒間隔だよね』
「そう。この例だと15秒間隔でオンになります。このタイマーは、この関
数で止めます」

// タイマーをキャンセルします。
void Cancel()
{
    LONG lCount = 0;
    BOOL b = CancelWaitableTimer( g_hTimer );
    TRACE( "%d\n", b );
}

『これで止めるまで止まらない?』
「そういうこと。というわけで次回は実際に使ってみます」

/*
    Preview Next Story!
*/
『タイマーって、ネットで調べてもあまり例ないよね』
「ちょっと使い方が難しいっていうのもあるけど……
『けど?』
「一番の理由は、使い道がないことかな」
『使い道ないの?』
「というわけで次回」
< Version 14.11 タイマーを使ってみる! >
『につづく!』
「ないっていうか、はっきりしないって言うか……」
『おまえがはっきりしろ』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。