#pragma twice

KAB-studio > プログラミング > #pragma twice > 280 Version 14.13 イベントを使ってみる!

#pragma twice 280 Version 14.13 イベントを使ってみる!

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

 Version 14.13
イベントを使ってみる!

というわけで、今回は実際にイベントを使ってみます
はーい
前回作った関数はこの7つ

void Create()
void Open()
void Set()
void Wait()
void Reset()
void Pulse()
void Close()

この7つのメソッドを、他の同期オブジェクトの時みたいに、次のふたつ
のプログラムで呼び出すようにしてください

ProcessA
ProcessB
ProcessC

イベントは3つで試すんだ
ひとつはイベントの作成と操作、残りふたつは待機、ってするから
なるほど
まず、 ProcessA でイベントを作ります

ProcessA::Create()

前回のプログラムでは、 CreateEvent() の第3引数に FALSE を渡してい
るので、この作ったばかりの時にはシグナルがオフになっています
シグナルオフ、ね
次に、ふたつのプロセスでこのイベントを待機します。まずは 
ProcessB と ProcessC で、今作ったイベントを取得します

ProcessB::Open()
ProcessC::Open()

これは他の同期オブジェクトと同じね
次にこのイベントを待機します

ProcessB::Wait()
ProcessC::Wait()

あ、両方とも〈待機開始〉で止まった
シグナルはオフの状態だから、この状態でイベントを監視すると待機しま

これも他の同期オブジェクトと同じね
さて、ここからが他の同期オブジェクトと違うところです。まず、 
ProcessB と ProcessC のアウトプットウィンドウが同時に見えるようにし


VC を並べるような感じで、縦に並べるのがいいかな
うん、並べたよ
次に、 ProcessA でイベントのシグナルをオンにします

ProcessA::Set()

あ! ProcessB と ProcessC 、両方とも待機終了した!
イベントの特徴のひとつは、シグナルをオンにすると、監視対象すべてに
それが知らされるということです
ミューテックスとかセマフォだと、ひとつずつだったもんね
バトンって概念があったからね。イベントの場合は数を制限しないものっ
てこと
セマフォよりセマフォらしいというか……
これを図にするとこうなります

ProcessA            ProcessB        ProcessC
イベント作成
(デフォルトで  →→イベント取得
 シグナルオフ)→→→→→→→→→→イベント取得
シグナルオフを←←←待機開始
を維持……←←←←←←←←←←←←←監視開始
シグナルオフ    (待機中)
を維持……             (待機中)
Set() で→→→→→→待機終了
シグナルオン→→→→→→→→→→→→待機終了

見にくい……
2行ずつ単位で見て
要するに、 Set() でイベントふたつとも待機終了する、って言いたいわ
けね
そういうこと。さて、イベントが他の同期オブジェクト違うもうひとつの
点が、シグナルの状態。イベントは、シグナルをオンにするとオンになりっ
ぱなしになります
なりっぱなし?
そう。この状態で監視すると、シグナルがオンなのですぐに待機終了しま


ProcessB::Wait()

あ、すぐに待機終了ってなっちゃった
イベントのシグナルはオンになりっぱなしだから
他の同期オブジェクトは……
他の同期オブジェクトは、シグナルオンはひとつのプロセスにしか知らさ
れないから。他のプロセスや、そのあと監視を始めたプロセスからは
シグナルはオフのまま
そか、他の同期オブジェクトだと、他のプロセスから見たらシグナルオフ
のままなんだね……
対して、イベントはそういうの関係なくて、どのプロセスから見ても状態
は同じだから
イベントを見てみたらシグナルがオンになりっぱなしのまま、ってわけ
ね……
そこで、シグナルをオフにしてみます

ProcessA::Reset()

これで、シグナルがオフになります。この状態のイベントを監視します

ProcessB::Wait()
ProcessC::Wait()

あ、両方とも待機開始で止まった
イベントの今の状態はシグナルオフだから
監視すると待機しっぱなしになる……
これが今回の最初の状態と同じってこと
で、 ProcessA::Set() をするとシグナルがオンになって、両方とも待機
終了する、と
そういうこと。では最後に〈パルス〉を使ってみます
 PulseEvent() のことね
科学用語では、〈パルス〉っていうのは一瞬だけ高い波が起きること。
電気とか電波とかそういう分野の用語かな
几みたいな?
几というよりは人みたいな
おお
では実際に使ってみます。さっきの

ProcessB::Wait()
ProcessC::Wait()

の待機が続いてる状態で、

ProcessA::Pulse()

を呼ぶと
両方とも待機終了した!
イベントがシグナルオンになって、それが両プロセスに通知されます
これだけだと ProcessA::Set() と同じだね
そう。違うのは、シグナルがオンになったあと、すぐにシグナルオフにな
るという点。もう一度監視してみるとわかるよ

ProcessB::Wait()
ProcessC::Wait()

あ、両方とも待機開始だ!
つまり、イベントはシグナルオフの状態ってことです
パルスは、一瞬だけシグナルオンになって、すぐにシグナルオフにな
る……
これを図にするとこうなります

ProcessA            ProcessB        ProcessC
シグナルオフを←←←待機開始
を維持……←←←←←←←←←←←←←監視開始
シグナルオフ    (待機中)
を維持……             (待機中)
Pulse() で→→→→→→待機終了
シグナルオン→→→→→→→→→→→→待機終了
シグナルオフ
を維持……
シグナルオフを←←←待機開始
を維持……←←←←←←←←←←←←←←監視開始
シグナルオフ    (待機中)
を維持……             (待機中)
...

シグナルオンのあと、すぐにシグナルオフになるわけね
待機状態になっている同期オブジェクトを全リセット、でもそのあと監視
し始めた同期オブジェクトはそのまま待機させたい、っていう場合にいいか

というか……イベントってなんか使い道よくわからない
深く考えない方がいいかも。たとえば、 ProcessB と ProcessC で繰り返
し処理していたとします
 for とか while で?
それかタイマーを使って。そのループの開始時にイベントを監視するよう
にすると、 ProcessA でセット/リセットの切り替えでループの開始/停止
を切り替えられるんです
おお! そういえばそうだ
ミューテックスやセマフォは〈バトン〉だから数が限られていたけど、
イベントは監視する数に制限はないから
そう考えるとわかりやすいね。なんか一番わかりやすい同期オブジェクト
かも
最初からそう言ってるし……

/*
    Preview Next Story!
*/
次回はスレッドを作ってみます
あれ? 同期オブジェクトって5つなかったっけ
うん、5つあるよ
なんでそれやんないの?
実は
あ! もしかして!
というわけで次回
< Version 14.14 スレッドを作ってみる >
につづく! って言わせてよ!
ボケるだけでしょ?
うん
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。