C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[13]: Thread.Sleepについて


(過去ログ 44 を表示中)

[トピック内 23 記事 (1 - 20 表示)]  << 0 | 1 >>

■23524 / inTopicNo.1)  Thread.Sleepについて
  
□投稿者/ ともいま (1回)-(2008/08/18(Mon) 11:46:23)

分類:[VB.NET/VB2005] 

開発環境:WinXP Pro、使用言語:VB.NET2003

複数スレッドを作成し、各々のスレッドで無限ループにThread.Sleepを用いて
定期的に処理させるシステムを構築したのですが、
とあるシステムで2秒周期で処理させるため、
Thread.Sleep(2000)を設定しておいたのですが、
このSleep部分で2秒で制御が返らない場合が稀に発生しています。
このSleep部分の前後にタイムスタンプを残す仕組みを作って
実行したところ、ほとんどが2秒なのですが、稀に4秒とか5秒というのがありました。
どうも、原因を調べると他のスレッドの状態が影響しているようです。
このシステムでは、他のスレッドでエラーが発生したタイミングでたまに
発生しているようですが。

このスレッドの優先度をHIGHESTにしても変わりませんでした。

Thread.Sleepは指定した秒数で必ず制御が戻ると思っていたのですが、
必ずしもそうではないのでしょうか?
また、必ず指定した秒数で制御を戻す方法はないのでしょうか?

引用返信 編集キー/
■23525 / inTopicNo.2)  Re[1]: Thread.Sleepについて
□投稿者/ επιστημη (1249回)-(2008/08/18(Mon) 11:51:35)
επιστημη さんの Web サイト
> また、必ず指定した秒数で制御を戻す方法はないのでしょうか?

どの程度の精度が必要ですか?
「Sleep(200)にしておいて、10回に1回処理をする」
でも構わないなら楽ですね。

引用返信 編集キー/
■23531 / inTopicNo.3)  Re[1]: Thread.Sleepについて
□投稿者/ NyaRuRu (58回)-(2008/08/18(Mon) 12:45:40)
2008/08/18(Mon) 12:46:14 編集(投稿者)

No23524 (ともいま さん) に返信
> Thread.Sleepは指定した秒数で必ず制御が戻ると思っていたのですが、
> 必ずしもそうではないのでしょうか?

保証はされておりません.

> また、必ず指定した秒数で制御を戻す方法はないのでしょうか?

一般的なデスクトップ用途の Windows では存在しません.
そのような機能を持つ,サードパーティー製の特殊なミドルウェア (Windows 用リアルタイムカーネル) は存在すると聞いたことがあります.
引用返信 編集キー/
■23532 / inTopicNo.4)  Re[1]: Thread.Sleepについて
□投稿者/ 渋木宏明(ひどり) (852回)-(2008/08/18(Mon) 12:46:12)
渋木宏明(ひどり) さんの Web サイト
> Thread.Sleepは指定した秒数で必ず制御が戻ると思っていたのですが、
> 必ずしもそうではないのでしょうか?

「まったく」そうではありません。

少なくとも引数で指定した待機時間の間だけ、スレッドがスケジュールされなくなるだけです。
待機時間経過後、いつそのスレッドが実行されるかはスケジューラの都合次第です。

Windows はリアルタイムOSではないので、厳密な時間管理は不可能です。
優先度の高い処理要件があれば、優先度の低い処理要件はいくらでも後回しにされます。

> どうも、原因を調べると他のスレッドの状態が影響しているようです。

それ以外にも様々な要因があります。
引用返信 編集キー/
■23535 / inTopicNo.5)  Re[2]: Thread.Sleepについて
□投稿者/ επιστημη (1251回)-(2008/08/18(Mon) 13:16:21)
επιστημη さんの Web サイト
代わりに System.Threading.Timer はいかがでしょうか。
ちっとはマシかも知れません。

引用返信 編集キー/
■23544 / inTopicNo.6)  Re[3]: Thread.Sleepについて
□投稿者/ ともいま (2回)-(2008/08/18(Mon) 15:24:38)
みなさん早速の回答有難う御座います。
みなさんの素晴らしいご意見を頂き、嬉しく思っています。

今回の投稿に関して具体的な問題内容を記載していなかったので
下記に記載します。

今回問題になっている2秒間Sleepさせる仕様なのですが、
このループ処理で上位PCにウォッチドッグコマンドを送信しているのですが、
送信している上位PCが5秒以上ウォッチドッグコマンドを受信できないと
異常警報が発生する仕様なので、
Sleep処理で4秒〜5秒位制御が返らないと警報が発生してしまう事態になってしまいます。
ですので、そこまで厳密にはSleepする秒数を求めていないのですが、
指定秒数の倍近く制御が戻らないのが問題となっています。
コンマ何秒のズレは仕方ないのですが、指定秒数の倍近く(数秒単位)制御が戻らないなんてことは
あるのでしょうか?


渋木宏明(ひどり)様
>Windows はリアルタイムOSではないので、厳密な時間管理は不可能です。
>優先度の高い処理要件があれば、優先度の低い処理要件はいくらでも後回しにされます。
このスレッドの優先度をHIGHESTにしても状況は変わらなかったのですが、
これはプログラム自体の優先度が影響しているのでしょうか?


επιστημη様
>代わりに System.Threading.Timer はいかがでしょうか。
これからTimerを使用して試してみます。



引用返信 編集キー/
■23547 / inTopicNo.7)  Re[4]: Thread.Sleepについて
□投稿者/ επιστημη (1252回)-(2008/08/18(Mon) 15:30:16)
επιστημη さんの Web サイト
> このループ処理で上位PCにウォッチドッグコマンドを送信しているのですが、
> 送信している上位PCが5秒以上ウォッチドッグコマンドを受信できないと
> 異常警報が発生する仕様なので、

番犬に餌をやるだけの簡単なお仕事なら

「Sleep(1000)にしておいて、2回に1回餌をやる」

で十分じゃないかしら。

引用返信 編集キー/
■23549 / inTopicNo.8)  Re[5]: Thread.Sleepについて
□投稿者/ ともいま (3回)-(2008/08/18(Mon) 15:39:48)
επιστημη様、早速の回答有難う御座います。

No23547 (επιστημη さん) に返信
>>このループ処理で上位PCにウォッチドッグコマンドを送信しているのですが、
>>送信している上位PCが5秒以上ウォッチドッグコマンドを受信できないと
>>異常警報が発生する仕様なので、
>
> 番犬に餌をやるだけの簡単なお仕事なら
>
> 「Sleep(1000)にしておいて、2回に1回餌をやる」
>
> で十分じゃないかしら。
>
Sleep(1000)も試したのですが、やっぱりこの時も4秒近く制御が戻らない時がありました。
その他に、Sleep(4000)の場合ですと、6秒近く制御が戻らない時があり、
Sleep(10000)にすると必ず10秒で制御が戻っています。
引用返信 編集キー/
■23552 / inTopicNo.9)  Re[6]: Thread.Sleepについて
□投稿者/ επιστημη (1254回)-(2008/08/18(Mon) 15:47:47)
επιστημη さんの Web サイト
> Sleep(1000)も試したのですが、やっぱりこの時も4秒近く制御が戻らない時がありました。

んーむ...スレッドを占有して悪さしてる輩がいたりしませんか?
たとえば「Sleep(200)にしておいて、10回に1回餌をやる」でとりあえず落ち着かせ、
並行して悪者を探した方が(悪気があってやってるんじゃ無いかも知れんけど、
いずれにせよ理由は掴んでおいた方が)あとあとのトラブルシューティングに役立つ
んじゃないかと。

引用返信 編集キー/
■23553 / inTopicNo.10)  Re[7]: Thread.Sleepについて
□投稿者/ やじゅ (545回)-(2008/08/18(Mon) 16:01:24)
やじゅ さんの Web サイト
ガベージコレクションが起きてる可能性もあるので、下記参照してみるとか
.NETアプリを軽快にするためのガベージ・コレクション講座
http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld06/directxworld06_01.html
引用返信 編集キー/
■23554 / inTopicNo.11)  Re[4]: Thread.Sleepについて
□投稿者/ れい (733回)-(2008/08/18(Mon) 16:03:52)
No23544 (ともいま さん) に返信
> コンマ何秒のズレは仕方ないのですが、指定秒数の倍近く(数秒単位)制御が戻らないなんてことは
> あるのでしょうか?

しょっちゅうあってもおかしくないです。
仕様を検討しなおすしかないですね。

Real TimeなLinuxとかが安くていいのでは。

> Sleep(10000)にすると必ず10秒で制御が戻っています。

これも、時と場合によりけり。
10秒は戻ってこないことしか保証できないです。
引用返信 編集キー/
■23556 / inTopicNo.12)  Re[4]: Thread.Sleepについて
□投稿者/ 渋木宏明(ひどり) (853回)-(2008/08/18(Mon) 16:17:39)
渋木宏明(ひどり) さんの Web サイト
> コンマ何秒のズレは仕方ないのですが、指定秒数の倍近く(数秒単位)制御が戻らないなんてことは
> あるのでしょうか?

保証が無いとは言え、いささか極端な状況だとは思います。

誰かがどこかでとてつもなく重たい処理を行っているのか、実行環境が極端によわっちいってことはありませんか?

> このスレッドの優先度をHIGHESTにしても状況は変わらなかったのですが、
> これはプログラム自体の優先度が影響しているのでしょうか?

もあり得ます。

プロセスの優先度クラスが低かったりすると、スレッド優先度をあげても目覚ましい効果が無かったりもします。

引用返信 編集キー/
■23558 / inTopicNo.13)  Re[5]: Thread.Sleepについて
□投稿者/ なちゃ (160回)-(2008/08/18(Mon) 16:36:22)
秒単位で長く帰って来ないのは、何か原因があると思います。
もちろん有り得ない現象ではないけど、そうそう起こる事でもない。

他に優先度が高いスレッドが重い処理してるとか、何かしてないですかね?
GCも考えられるけど、javaと違ってフルGCでも、何秒もかかるイメージはあまりないですね…
非常にメモリを使う処理があって、物理メモリが少ないとかならあるのかな?


引用返信 編集キー/
■23561 / inTopicNo.14)  Re[5]: Thread.Sleepについて
□投稿者/ ともいま (4回)-(2008/08/18(Mon) 17:04:42)
皆さん、有効な回答を色々と有難う御座います。

No23556 (渋木宏明(ひどり) さん) に返信
> 誰かがどこかでとてつもなく重たい処理を行っているのか、実行環境が極端によわっちいってことはありませんか?
確かに2秒Sleepで4秒間制御が戻らない時にCPUの負荷は若干上がっています。
テストした環境はCPU:PentiumD2.8G、メモリ1GBで、片方のCPUが数秒間50%程度になるタイミングで
Sleepの戻り遅れが発生しています。

別スレッドで他の機器にTCPCLIENTを用いてCONNECT処理を行っているのですが、
その相手のポートが閉じている場合、エラーが発生しCATCHされるタイミングでCPUの負荷が若干上がっています。
どうもそのタイミングでSleepの戻りが遅くなっているようです。
このスレッドを動作させないと今のところ、Sleepの遅れは発生していません。
今回判明したタイミングは1つの要因であって、他にも要因があると睨んでいます。

スレッド間でこういった影響は頻繁にあるものなのでしょうか?





引用返信 編集キー/
■23566 / inTopicNo.15)  Re[6]: Thread.Sleepについて
□投稿者/ 渋木宏明(ひどり) (854回)-(2008/08/18(Mon) 18:00:50)
渋木宏明(ひどり) さんの Web サイト
> 別スレッドで他の機器にTCPCLIENTを用いてCONNECT処理を行っているのですが、
> その相手のポートが閉じている場合、エラーが発生しCATCHされるタイミングでCPUの負荷が若干上がっています。
> どうもそのタイミングでSleepの戻りが遅くなっているようです。

その程度で Sleep(2000) が4秒も返ってこないのは変ですねぇ。

ありそうもないけど、ドライバが相当お馬鹿な作りとか?

> スレッド間でこういった影響は頻繁にあるものなのでしょうか?

既に述べたとおり、Windows はリアルタイムOSではないので、「影響ある」のは間違いありません。

ですが、具体的にどれだけ遅延するとか、どれくらい頻繁に起きるのかについては、実行環境の性能や実行されている処理の内容等々によって大きな差があるため、確定的なことは何も言えまえん。

ただ、現象が極端な気はするので、他に何か原因があるようには感じます。

引用返信 編集キー/
■23572 / inTopicNo.16)  Re[6]: Thread.Sleepについて
□投稿者/ まどか (579回)-(2008/08/18(Mon) 19:54:59)
No23561 (ともいま さん) に返信
> 別スレッドで他の機器にTCPCLIENTを用いてCONNECT処理を行っているのですが、
> その相手のポートが閉じている場合、エラーが発生しCATCHされるタイミングでCPUの負荷が若干上がっています。
> どうもそのタイミングでSleepの戻りが遅くなっているようです。

タイムアウト(エラー発生)になるまで低レベルIOしてるから?
引用返信 編集キー/
■23588 / inTopicNo.17)  Re[7]: Thread.Sleepについて
□投稿者/ ともいま (5回)-(2008/08/18(Mon) 23:30:59)
みなさん、色々とご意見有難う御座います。

渋木宏明(ひどり)様
>既に述べたとおり、Windows はリアルタイムOSではないので、「影響ある」のは間違いありません。
>ですが、具体的にどれだけ遅延するとか、どれくらい頻繁に起きるのかについては、実行環境の性能や実>行されている処理の内容等々によって大きな差があるため、確定的なことは何も言えまえん。
>ただ、現象が極端な気はするので、他に何か原因があるようには感じます。

確かに今まで記載した2秒Sleepのスレッドとソケットでエラーを発生させるスレッドを実行する簡単なアプリを作成しても同様の結果は得られませんでしたし、
実際のアプリでは、対象のスレッド以外にもデータ収集スレッドや定時処理スレッドなど
何本もスレッドを起動させているので、今回記載したCONNECTでエラーだけが原因ではありません。
また、実際の運用環境は、CONNECTでエラーになるようなこともない(はず?)ですが
問題になっている現象が2,3ヶ月に1度発生しているのが現状です。
発生時間はまちまちで特に何かの処理を行っている時間帯ではないです。

たまたまテスト環境で機器を全て揃えられなくて、
> 別スレッドで他の機器にTCPCLIENTを用いてCONNECT処理を行っているのですが、
> その相手のポートが閉じている場合、エラーが発生しCATCHされるタイミングでCPUの負荷が若干上がっています。
このタイミングで実環境と同じ現象を再現できたというだけです。

また、補足なのですが、
上記のTCPCLIENTのCONNECT処理も正常に接続できるまでループ処理を行っているのですが、
システム起動1発目のエラーをCATCHした時のみSleepの遅れが発生しています。
2発目以降のCATCHでは、同様の遅れは発生していません。





引用返信 編集キー/
■23589 / inTopicNo.18)  Re[8]: Thread.Sleepについて
□投稿者/ 渋木宏明(ひどり) (856回)-(2008/08/19(Tue) 00:17:42)
渋木宏明(ひどり) さんの Web サイト
> システム起動1発目のエラーをCATCHした時のみSleepの遅れが発生しています。
> 2発目以降のCATCHでは、同様の遅れは発生していません。

じゃあ JIT かな。

そのスレッドが初めて実行される時、IL がマシンコードに変換されます。
その変換が終わるまで、メソッドの実行は遅延します。

これに関しては、ngen ユーティリティを使うことで低減できる場合があります。

引用返信 編集キー/
■23593 / inTopicNo.19)  Re[9]: Thread.Sleepについて
□投稿者/ 小心者 (3回)-(2008/08/19(Tue) 01:05:01)
1)監視周期の適正値を再検討しできるだけ大きくとる。
2)細切れ(0.1秒毎程度)にSleepしてシステム時刻の秒の変化をカウントする。

個人的には番犬が5秒しか我慢できないのが気になります。

ところで監視対象の処理は1周期何秒で終わるべきで、
実際何秒かかっているのでしょうか?
引用返信 編集キー/
■23599 / inTopicNo.20)  Re[10]: Thread.Sleepについて
 
□投稿者/ ともいま (6回)-(2008/08/19(Tue) 08:48:16)
みなさん、参考になる回答有難う御座います。

No23593 (小心者 さん) に返信
> 1)監視周期の適正値を再検討しできるだけ大きくとる。
実環境でどれだけ遅延が発生しているか調査する仕組みを組み込んで
しばらく調査する予定です。

> 個人的には番犬が5秒しか我慢できないのが気になります。
顧客の要望仕様なので...。ただ、とりあえずの回避策として
上記の調査結果が出た後、顧客に監視周期を伸ばしてもらうよう
交渉はするつもりです。
ただ、根本的な原因の追究はできていないので、
この機会に解明したいと思いまして。

> ところで監視対象の処理は1周期何秒で終わるべきで、
> 実際何秒かかっているのでしょうか?
監視対象の処理自体は、たいした処理をしている訳ではないので、
かかる秒数は限りなく0に近いはずと考えています。
ただ単に次の処理まで2秒間開けたいのでSleep(2000)を挟んでいるだけです。
実際各々のコード1行1行にタイムスタンプを取るようにして調査したところ、
大体は思った通り2秒周期で正常に動作しています。
で、Sleep(2000)の前後のスタンプで4秒近く差が出る場合があったので
今回の事象に気が付きました。

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -