Version 14.11
タイマーを使ってみる!
「というわけで、今回は実際に、同期オブジェクトのタイマーを使ってみま
す」
『タイマーっていうとわかりやすい感じがするんだけど、でも使い方の
イメージがつかめない……』
「それは普通のタイマーを考えてるからじゃないかな。このタイマーは同期
オブジェクトのタイマーなんだから、他の同期オブジェクトと同じように使
えばいいんです」
『他の同期オブジェクトと同じ……待ってるとシグナルオン、みたいな?』
「そういうこと。というわけで、まず一番簡単な方法、自分で作って自分で
待ってみます。他の同期オブジェクトと同じように、まず」
void Create()
void Open()
void Set()
void Wait()
void Cancel()
void Close()
「の6個の関数をボタンから呼び出すようにしてください。ただ、 Set()
が追加されているのと、 Release() が Cancel() に変更されているので注
意してください」
『ボタンひとつ追加ねー』
「それでは使ってみましょう」
Create()
Set()
「この順で呼び出すことで、タイマーがセットされて、15秒ごとにオンに
なるようになります」
『この〈オン〉っていうのが……』
「〈シグナルがオンになる〉って言えばわかるでしょ」
『あ! そか、同期オブジェクトなんだもんね』
「そういうこと」
Wait()
「でこのタイマーを監視してみます」
『あれ? すぐ〈待機終了〉になっちゃった』
「運が悪かったかも……もう一度やってみて」
『ほい……あ、今度はちょっとしてから〈待機終了〉になった』
「どういうことかっていうと、最初にタイマーがオンになってから、15秒
間隔でオンになるんです」
SetWaitableTimer() 呼び出し
5秒待機……
シグナルオン
15秒待機……
シグナルオン
15秒待機……
シグナルオン
15秒待機……
「という流れになります。途中で WaitForSingleObject() を監視するとこ
うなります」
タイマー ProcessA
タイマーセット←←←←←←←←←←SetWaitableTimer()
5秒待機……
シグナルオン
15秒待機……←←←←←←←←←←WaitForSingleObject() 待機開始。
シグナルオン→→→→→→→→→→→待機終了。
15秒待機……
「この〈15秒待機〉の間のいつ〈待機開始〉しても、シグナルオンになっ
たら〈待機終了〉になります」
『待ち始めた時間は関係ないわけね』
「そういうこと」
『……でもさ、なんかいまいち使い道わかんない。待ち始めた時間に関係な
いんじゃ、 SetWaitableTimer() したらすぐ WaitForSingleObject() して
一定時間後に、って感じじゃない』
「それは自分だけしか使ってないから。タイマーは複数のプロセスから同時
に監視するときに威力を発揮するんです」
ProcessA
ProcessB
「のふたつを作って、両方とも各ボタンで各関数を呼び出すようにしてくだ
さい」
『いつも通りな感じね。あれ、でもみっつ作らなくていいの?』
「今回はふたつで十分だから大丈夫。さて、まずは準備から」
ProcessA::Create()
ProcessB::Open()
ProcessA::Set()
『 ProcessA で作って ProcessB は開くだけ、ね』
「それでは待機を開始してみます」
ProcessA::Wait()
ProcessB::Wait()
『両方いっぺんに待つ、と……』
ProcessA::待機開始
ProcessB::待機開始
……数秒後……
ProcessA::待機終了
……15秒後……
ProcessB::待機終了
『お、最初は ProcessA しか待機終了しないんだね』
「他の同期オブジェクトもそうだったでしょ」
『そういえば、ミューテックスもセマフォも、シグナルがオンになった時、
待機終了するのは最初に待機した方ひとつだけ……』
「流れはこうなります」
タイマー ProcessA ProcessB
セット←←←←←←←タイマーセット
5秒待機……
シグナルオン
2秒待機……←←←←待機開始
3秒待機……←←←←←←←←←←←←←待機開始
10秒待機……
シグナルオン→→→→待機終了
15秒待機……
シグナルオン→→→→→→→→→→→→→待機終了
15秒待機……
「最初に待機開始した ProcessA が先に待機終了して、次のシグナルオンで
ProcessB の待機が終了します」
『シグナルオンで待機終了するのはひとつずつ、ってことね』
「この具体的な使い道というかイメージは、セマフォと同じくバトンで考え
ると、 ProcessA から ProcessE まである場合……」
ProcessA:待機開始→待機中……
ProcessB:待機開始→待機中……
ProcessC:待機開始→待機中……
ProcessD:待機開始→待機中……
ProcessE:待機開始→待機中……
「と、それぞれ WaitForSingleObject() が呼ぶとこういう状態になりま
す」
『5つとも全部待機状態なわけね』
「それから数秒後、シグナルオンになると」
ProcessA:待機終了→処理開始!
ProcessB:待機開始→待機中……
ProcessC:待機開始→待機中……
ProcessD:待機開始→待機中……
ProcessE:待機開始→待機中……
「それから15秒後」
ProcessA:処理中……(もしくは処理終了)
ProcessB:待機終了→処理開始!
ProcessC:待機開始→待機中……
ProcessD:待機開始→待機中……
ProcessE:待機開始→待機中……
「さらに15秒後……」
ProcessA:処理中……(もしくは処理終了)
ProcessB:処理中……(もしくは処理終了)
ProcessC:待機終了→処理開始!
ProcessD:待機開始→待機中……
ProcessE:待機開始→待機中……
「という感じに、タイマーにセットした間隔で処理が開始していきます」
『なんか花火に火を付けていって、ひとつずつ上がっていくみたいな感じ
ね〜』
「セマフォの場合と比較して考えてみます」
セマフォ(バトン数が3の場合)
ProcessA:バトンを受け取って処理開始
ProcessB:バトンを受け取って処理開始
ProcessC:バトンを受け取って処理開始
ProcessD:待機開始→待機中……(バトンが空いたら処理開始)
ProcessE:待機開始→待機中……
「セマフォの場合はバトンの数で実行される処理数を限定します」
『バトンが3つなら3つだけ、ってことね』
「それに対してタイマーは、最大数はプロセスの数5つっていうだけで、そ
れ以外の制限はありません」
『全部処理開始したら全部で5つ処理中ってわけね』
「ただ、最初はそういうことはないでしょ」
『 A 、B 、C って少しずつ増えていくんだもんね。最初は大変な状態になら
ないってわけね』
「それに、処理が一定時間で終了するなら」
『 D が始まる前に A が終了したら、全部で 3つだけ処理される、ってわ
けね。そういう意味では数が制限されるんだ』
「そういう、ちょっと曖昧な感じで、数の制限をしたい場合にこのタイマー
は便利です。たとえばマシンやネットワークの負荷を下げるためとか」
『しっかり3個だけ、とかしないけど、全部いっぺんに処理、ってしないわ
けね』
「まぁその分、使い道があまりはっきりしないからあまり使われてないけど
ね……」
/*
Preview Next Story!
*/
『タイマーもわかりやすいね。使い道はよくわからないけど』
「次のイベントはもっとわかりやすいよ」
『タイマーよりも?』
「同期オブジェクトの中で一番簡単」
『おー』
「というわけで次回」
< Version 14.12 イベントを使おう! >
『につづく!』
「シグナルやバトンって考え方が必要ないから本当に簡単」
『……なんかそれは逆に難しそうな』
「え……」