WaitForSingleObject( …, 0 )は、リセット作用がある? – プログラミング – Home

通知
すべてクリア

[解決済] WaitForSingleObject( ..., 0 )は、リセット作用がある?


おもち
 おもち
(@おもち)
ゲスト
結合: 17年前
投稿: 18
Topic starter  

早速で恐縮ですが、下のコード時、
「最下行のWaitForSingleObject()から返った時は、リセット(非シグナル)状態」
でしょうか?( 各APIは、全て処理が成功しているものとします )

HANDLE h( CreateWaitableTimer( NULL, FALSE, " ) );
LARGE_INTEGER DueTime;
DueTime.QuadPart = -1LL; // 100ns後に即シグナル化
SetWaitableTimer( h, &DueTime, 0, NULL, NULL, FALSE );
Sleep( 1 ); // 1ms待機.故に,タイマはシグナル状態
WaitForSingleObject( h, 0 );

私は「リセット状態ではない」と思っています。
「第2引数が0なので、シグナル状態の検査のみを行う機能になっている。
従ってシグナル化待機と自動リセット(非シグナル化)はされない」
と考えた為です。
が、同僚は「リセット状態」という意見でした。

テストプログラムでもよく分からなかった為、皆様に意見を伺った次第です。
どうぞ宜しくお願い致します。


引用未解決
トピックタグ
おもち
 おもち
(@おもち)
ゲスト
結合: 17年前
投稿: 18
Topic starter  

環境の記載を忘れておりました。
WinXP Pro. + 最新パッチ、VC++8

失礼しました。


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

CreateWaitableTimerを知らないので推測

DueTimeを数秒にして
for(int i = 0; i < 10; ++i) {
Sleep( 1 );
w = WaitForSingleObject( h, 0 );
TRACE(%d\n,w);
}
にすればいいんじゃない。
自動リセットなら数秒後に一度だけw=WAIT_OBJECT_0で
あとはw=WAIT_TIMEOUTじゃないのかな。
手動リセットなら始めw=WAIT_TIMEOUTで
数秒後はずーっとw=WAIT_OBJECT_0じゃないのかな。


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

秒のケタ間違えてた


返信引用
玲音 (st.lain)
 玲音 (st.lain)
(@玲音 (st.lain))
ゲスト
結合: 17年前
投稿: 89
 

びみょ~な単位時間でのタイマーの扱いは不慣れなので、ちょい不安ですが。

> HANDLE h( CreateWaitableTimer( NULL, FALSE, " ) );
最後の"って大丈夫でしょうか? 空文字の場合はNULL指定の場合の名前なしと
別の扱いを受ける気がします。(結果に対しての影響はないハズですが)

> DueTime.QuadPart = -1LL; // 100ns後に即シグナル化
-1Lの誤記、カナ?

> Sleep( 1 ); // 1ms待機.故に,タイマはシグナル状態
コメントに書いてあるように、このステートメントが完了した時点でシグナルな
はずなので、WaitForSingleObject()はWAIT_OBJECT_0が返るのでは、と予測
します。

> テストプログラムでもよく分からなかった為
よく分からなかった、とはどゆ意味でしょうか?

# 100ns, 1msのような短時間での検証の必要性はあるのでしょうか?
# 特にそのようにする必要がないように思われます。


返信引用
玲音 (st.lain)
 玲音 (st.lain)
(@玲音 (st.lain))
ゲスト
結合: 17年前
投稿: 89
 

>> DueTime.QuadPart = -1LL; // 100ns後に即シグナル化
> -1Lの誤記、カナ?
LONGLONGの時って、LLと書けたのですね。初めて知りました m(__)m


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

「WaitForSingleObject( h, 0 );」について、
MSDN CDより、
> 0 を指定すると、この関数は指定されたオブジェクトの状態を調べ、
> 即座に制御を返します。
別に「リセット状態」とか「非リセット状態」とか関係なく、
待たずにすぐ制御を戻すだけだと思います。
後は戻り値で判断ですね。
WAIT_ABANDONED、WAIT_OBJECT_0、WAIT_TIMEOUT、WAIT_FAILED
詳細は、MSDN CDを参考してください。

> Sleep( 1 ); // 1ms待機
1msは間違えです。少なくとも10mS以上は掛かります。
(マイクロソフト承認)

> 従ってシグナル化待機と自動リセット(非シグナル化)はされない」
> と考えた為です。
> が、同僚は「リセット状態」という意見でした。
「CreateEvent」のパラメータ設定が手動で、かつ「WaitForSingleObject( h, 0 );」
でシグナルを認識したならば、「リセット状態」になる可能性があります。
きちんと手動でリセットしなければならないのであれば、一様「ResetEvent」は
入れておく必要があります。

> Sleep( 1 ); // 1ms待機
するならば、
「WaitForSingleObject( h, 10 );」
でWAIT_TIMEOUTかどうか調べるだけでいいと思います。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

やってみりゃーいいじゃないのー。

以下のように修正して実行。

HANDLE h( CreateWaitableTimer( NULL, FALSE, NULL ) );
LARGE_INTEGER DueTime;
DueTime.QuadPart = -1LL; // 100ns後に即シグナル化
SetWaitableTimer( h, &DueTime, 0, NULL, NULL, FALSE );
Sleep( 1 ); // 1ms待機.故に,タイマはシグナル状態
DWORD dw = WaitForSingleObject( h, 0 );
dw = WaitForSingleObject( h, 0 );

1回目のWaitForSingleObjectの戻り値はWAIT_OBJECT_0、2回目は WAIT_TIMEOUT となりま
した。
従って、1回目のWaitForSingleObjectから戻った時点では非シグナル状態、ということに
なります。

…これじゃダメなの?


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

とりあえず、

> テストプログラムでもよく分からなかった為、皆様に意見を伺った次第です。
> どうぞ宜しくお願い致します。

シャノンさんが提示されているような方法でわかるはずなのに
なぜ解らなかったのかの方が興味あります。
ぜひ説明をお願いします。


返信引用
おもち
 おもち
(@おもち)
ゲスト
結合: 17年前
投稿: 18
Topic starter  

結論は「WaitForSingleObject( ???, 0 )は、非シグナル化(リセット)しない」で、当初
の予想通りでした。冒頭のコードに下記を加えるだけの簡単な検証で出来ました。
wclrp ( 'o')さんの回答に酷似した結果です。

while( 1 ){
switch( WaitForSingleObject( hTimer, 0 ) ){
case WAIT_ABANDONED:
OutputDebugString( WAIT_ABANDONED\n );
break;
case WAIT_OBJECT_0:// シグナル 検出
OutputDebugString( WAIT_OBJECT_0\n );
break;
case WAIT_TIMEOUT: // 非シグナル(リセット) 検出
OutputDebugString( WAIT_TIMEOUT\n );
}
}

数十回実行後の表示結果を纏めると下のようになりました。
・まず数回WAIT_TIMEOUT。表示回数は実行毎に変動
・直後に1回だけWAIT_OBJECT_0。
・その後はずっとWAIT_TIMEOUT。
上記ループ直前のWaitForSingleObject()を削除すると、期待通りWAIT_TIMEOUTのみでし
た。

とあるH/W(MS製SDK(Win32API互換)が実装されてる非PCマシン)でも、同じような動きでし
た。

>最後の"って大丈夫でしょうか? 空文字の場合はNULL指定の場合の名前なしと
>別の扱いを受ける気がします。(結果に対しての影響はないハズですが)
今回の実験では問題外故、適当な引数にしました。
因みにPCでは大丈夫です。が、上記のあるH/Wでは、CreateWaitableTimer()がNULLを返
します。

># 100ns, 1msのような短時間での検証の必要性はあるのでしょうか?
># 特にそのようにする必要がないように思われます。
必要です。極めて短い時間を取り扱う案件の為です。

>待たずにすぐ制御を戻すだけだと思います。
全くその通りでした。

>1msは間違えです。少なくとも10mS以上は掛かります。
未だにそうなのですね。MSDNに載ってなかった為、改善済だと思いました。
情報元を探してみます。OSにより仕様が違う可能性もありますし...。

>「WaitForSingleObject( h, 10 );」でWAIT_TIMEOUTかどうか調べるだけでいい
いえ、今回は「WaitForSingleObject( h, 0 )がシグナル状態の検査以外の処理をする
か?」だけを知る必要があったんです。

>1回目のWaitForSingleObjectから戻った時点では非シグナル状態、ということになりま

いえ、繰り返すとそうならない事が分かりました。でも、有難うございました。

皆さん、どうも有難うございました。


返信引用
おもち
 おもち
(@おもち)
ゲスト
結合: 17年前
投稿: 18
Topic starter  

言い忘れておりました。Sleep(1)は削除して実験しました。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> ・まず数回WAIT_TIMEOUT。表示回数は実行毎に変動
> ・直後に1回だけWAIT_OBJECT_0。
> ・その後はずっとWAIT_TIMEOUT。

どうして、この結果から、

> WaitForSingleObject( ???, 0 )は、非シグナル化(リセット)しない

という結論が出るのかわからないんですが。

WaitForSingleObject( handle, 0 ) がタイマをリセットしないなら、自動リセットタイ
マであってもリセットされない=手動リセットと同じ、一度シグナル状態になったら、
SetWaitableTimerしない限りずーっとシグナル状態、であるはずです。
ならば、一旦 WAIT_OBJECT_0 になったあとは、ずーっと WAIT_OBJECT_0 でないといけな
いでしょう。
WAIT_OBJECT_0 が一度だけということは、待ち時間が 0 であってもリセットされている
ことの証拠なのでは?


返信引用
おもち
 おもち
(@おもち)
ゲスト
結合: 17年前
投稿: 18
Topic starter  

>WAIT_OBJECT_0 が一度だけということは、待ち時間が 0 であってもリセットされている
ことの証拠なのでは?

確かに言われてみればそうですね。
#何で納得していたんだろう...?頭を冷やします...
前言は撤回で、「待ち時間0でもリセット機能を有する」というのが正しそうですね。

どうも有難うございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました