SetWaitableTimer 待機可能タイマの設定

Cの宣言:

BOOL SetWaitableTimer(
	HANDLE hTimer,
	const LARGE_INTEGER *DueTime,
	LONG Period,
	PTIMERAPCROUTINE Completion,
	LPVOID Args,
	BOOL Resume);

説明:

タイマオブジェクトの状態を設定し、タイマオブジェクトを有効にする。

この関数は、NT4.0以降で使用可能である。

SetWaitableTimer関数を実行すると、タイマオブジェクトはDueTimeで指定された時間の経過後シグナル状態となり、以後Periodで指定された時間ごとにシグナル状態となる。

DueTimeは100ナノ秒単位である。Periodはミリ秒単位である。1秒は1000000000ナノ秒である。

DueTimeは64bit値であり、二つの指定方法がある。DueTimeで指定した値が負の値である場合、現在の時刻から最初のイベント発生までの時間間隔を指定したことになる。DueTimeで指定した値が正の値である場合、最初のイベント発生のUTC時刻の1601/01/01からの経過時間を表す。この場合、現在の時間に相当する値を取得するには、GetSystemTime関数実行後SystemTimeToFileTime関数を実行する。

Completionには、タイマイベント発生時に実行する完了ルーチンを指定することができる。CompletionにNULL以外を指定すると、タイマイベントが発生するたびに、SetWaitableTimerの呼び出し元APCキューに完了ルーチンをためる。呼び出し元スレッドがアラート可能な待機状態になると、キューにためられた完了ルーチンが実行される。

引数の意味は、以下の通り。
hTimer タイマオブジェクトを示すハンドル。
DueTime 最初のイベント発生の時刻を示す値。
lPeriod イベントごとの時間間隔を指定する値。0を指定した場合、1度だけしかイベントは発生しない。
Completion 完了ルーチンへのポインタ。完了ルーチンを用いない場合、NULLを指定できる。
Resume イベント発生時にシステムを省電力モードへ移行させるか否かを表すフラグ。<http://www.microsoft.com/hwdev/desinit/onnowapp.htm>を参照。

関数の実行に成功した場合、TRUEが返される。失敗した場合、FALSEが返される。

完了ルーチンを用いない例:

スレッド作成から3秒後以降に、0.5秒ごとにスレッドの処理を行う。
#define TIMERNAME "Test Timer Object"

/* スレッド用関数 */
DWORD WINAPI DoThread(DWORD ThreadCount)
{
	HANDLE hTimer;
	int i;

	/* タイマオブジェクトのオープン */
	hTimer = OpenWaitableTimer(TIMER_ALL_ACCESS, FALSE, TIMERNAME);

	for(i=0; i<5; i++) {
		/* 待機 */
		WaitForSingleObject(hTimer, INFINITE);

		/* 処理 */
		printf("スレッド%d: 処理開始\n", ThreadCount);
		Sleep(100);
		printf("スレッド%d: 処理終了\n", ThreadCount);
	}

	/* 終了 */
	CloseHandle(hTimer);
	return(0);
}

int main(int argc, char **argv)
{
	HANDLE hThread[2];
	DWORD ThreadID[2];
	HANDLE hTimer;
	int i;
	LARGE_INTEGER li;

	/* タイマオブジェクトの初期化 */
	hTimer = CreateWaitableTimer(NULL, FALSE, TIMERNAME);

	/* スレッドを2つ作成 */
	for(i=0; i<2; i++) {
		hThread[i] = CreateThread(
			NULL, 0, (LPTHREAD_START_ROUTINE)DoThread,
			(LPVOID)i, 0, &ThreadID[i]);
	}

	li.QuadPart = -30000000;

	printf("開始\n");
	SetWaitableTimer(hTimer, &li, 500, NULL, &li, FALSE);

	/* スレッドの終了まで待機 */
	WaitForMultipleObjects(2, hThread, TRUE, INFINITE);


	/* 後処理 */
	CloseHandle(hTimer);

	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);

	return(0);
}

完了ルーチンを指定した例:

/* スレッド用関数 */
DWORD WINAPI DoThread(DWORD ThreadCount)
{
	HANDLE hTimer;
	int i;

	hTimer = OpenWaitableTimer(TIMER_ALL_ACCESS, FALSE, TIMERNAME);

	for(i=0; i<5; i++) {
		/* 所有権獲得まで待機 */
		WaitForSingleObject(hTimer, INFINITE);

		/* 処理 */
		printf("スレッド%d: 処理開始\n", ThreadCount);
		Sleep(100);
		printf("スレッド%d: 処理終了\n", ThreadCount);
	}

	CloseHandle(hTimer);
	return(0);
}

/* 完了ルーチン */
VOID APIENTRY TimerAPC(LPVOID Args, DWORD low, DWORD high)
{
	printf("TimerAPC Executed.\n");
}

int main(int argc, char **argv)
{
	HANDLE hThread[2];
	DWORD ThreadID[2];
	HANDLE hTimer;
	int i;
	LARGE_INTEGER li;

	/* タイマオブジェクトの初期化 */
	hTimer = CreateWaitableTimer(NULL, FALSE, TIMERNAME);

	/* スレッドを2つ作成 */
	for(i=0; i<2; i++) {
		hThread[i] = CreateThread(
			NULL, 0, (LPTHREAD_START_ROUTINE)DoThread,
			(LPVOID)i, 0, &ThreadID[i]);
		Sleep(1000);
	}

	li.QuadPart = 0;

	SetWaitableTimer(hTimer, &li, 500, TimerAPC, &li, FALSE);

	/* スレッドの終了まで待機 */
	while(WaitForMultipleObjectsEx(2, hThread, TRUE, INFINITE, TRUE) == WAIT_IO_COMPLETION);
	
	/* 後処理 */
	CloseHandle(hTimer);

	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);

	return(0);
}


メモ:

Resumeパラメータを試せる環境が無い。
(original text:1998/12/25 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。