- - PR -
処理が止まるようになった
1
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-03-10 15:59
いつもお世話になっております。
Windowsアプリケーションで、 クライアントからソケットで受信し、SQLSever2000との処理を行い、ソケットでクライアントに送信するという ものを作りました。 .NETFrameworkの System.Threading.Thread クラス System.Threading.Moniterクラス System.Collections.Queueクラス を特に使用して作成しています。 画面上とファイルにログを書く処理があり、その排他にMoniterクラスを使用しています。 このアプリケーションが稼働していたサーバが老朽のため、 新しいサーバに移行しました。 (旧サーバは、Windows Server 2000、2CPU) このアプリケーションは、.NETFramework1.0(VisualStudio2000でビルド)で構築しました。 新しいサーバでこのアプリケーション(プログラムの修正なし)、実行したら、非同期にスレッド内で処理が止まる現象が発生しました。 旧サーバでは、処理が止まるような現象は発生していませんでした。(5年間) 特にクライアントからのソケット受信後のMoniter.Enterを行ったときに1秒〜7秒、処理がとまるようです。 社内のサーバでもテストを行いましたが、現象が起きません。 このアプリケーションを.NETFramework1.1(VisualStudio2003でビルド)、 .NETFramework2.0(VisualStudio2005でビルド)と構築し直しましたが、現象が改善されません。 新サーバのスペックは以下の通りです。 CPU : クアッドコア インテル?Xeon?プロセッサーE5420(2×6MB L2キャッシュ 2.50GHz 1333MhzFSB)× 2 メモリー : 4GB(4×1GB 1R)667Mhz Fully Buffered DIMM ECC DRR2メモリ OS : Windows Server 2003 R2 Standard Edition with SP2 日本語版 ギガビットイーサネットコントローラ(NIC) × 2 新サーバには、iSCSIイニシエータを使用し、ストレージを増設しています。 社内のスペックは以下の通りです。 CPU : クアッドコア インテル?Xeon?プロセッサーX5365 @3.00GHZ メモリー : 4GB OS : Windows Server 2003 R2 Standard Edition with SP2 日本語版 このような現象の理由と解決方法を、ご存知の方がいましたら教えて頂きたいです。 宜しくお願いします。 | ||||||||||||||||
|
投稿日時: 2009-03-10 18:42
こんにちは。
全然回答にはなっていないのですが…
Moniter.Enterってスピンロックでブロックしているようですが、 ループに入れているPAUSE命令(rep nop)の待ち時間ってどのくらいの範囲あるのだろう??と思ってみたり IA-32 インテル ® アーキテクチャ ソフトウェア・デベロッパーズ・マニュアルより抜粋 http://download.intel.com/jp/developer/jpdoc/IA32_Arh_Dev_Man_Vol2B_i.pdf
確かめるには、こっち↓メソッドを使用したほうが良さそうであるけど、いろいろ試せるほど手元にPCが無い(汗) Thread.SpinWait メソッド | ||||||||||||||||
|
投稿日時: 2009-03-10 21:51
一番ありそうなのはコーディングミスで、例外発生時などにリリースしてないとか。
| ||||||||||||||||
|
投稿日時: 2009-03-10 21:51
一番ありそうなのはコーディングミスで、例外発生時などにリリースしてないとか。
| ||||||||||||||||
|
投稿日時: 2009-03-10 22:49
推理ですが、たぶん、こういう場合は、潜在化していたバグが、CPU数の違いで顕在化しただけだろうと思います。
一時的に、タスクマネージャーで、プロセスを選択して右クリックで「関係の選択」などを選び、CPUを1個だけにして動かしてみて、挙動が改善するかどうかを試されてはどうでしょうか。もしこれで改善したならば、ほかにもいろいろな方法でこういう指定ができますのでそのような回避方法でしのぐか、あるいは、CPU数がらみのバグを見つけて根本的に修正するか、のどちらかでしょうか。 | ||||||||||||||||
|
投稿日時: 2009-03-11 16:55
こんにちは。
私もそうでだろうとは予想しているのですが… (マルチスレッドプログラミングでは常識ですが)ロックは必要最小限の期間でちゃんとリリースしているのでしょうかね? リリースが遅いために、別スレッドでかなりの待ち時間が発生してしまっているとか!? あと以下余談(独り言)ですが…
計測してみると Celeron(2.66GZ)CPUでは、 PAUSE命令(rep nop命令)は1回あたり 約0.21μ秒程度でした。 NOPが(何もしないループと比較考慮すると)計測不能なくらい短いのに対して、かなり停止することが分かりました。 ただ何度か試しましたが、PAUSEの停止時間のブレはそんなにないように思いました。 C++コード
C#コード
| ||||||||||||||||
|
投稿日時: 2009-03-16 16:24
みなさん、回答ありがとうございました。 上記に書かれていることを試しましたが、解決できませんでした。 (タスクマネージャーで、プロセスを選択して右クリックで「関係の選択」などを選び、CPUを1個だけにして動かしてみる) ちなみにCPU数がらみのバグとは、どういったコードを組んだときなのでしょうか? ご回答、宜しくお願いたします。 | ||||||||||||||||
|
投稿日時: 2009-03-17 13:43
マルチスレッドのプログラムの場合、スレッド間の同期に関しては
能動的にタイミングを取らないと動作環境が変わった関係で動きが変わってしまうことは よくあります。同期オブジェクト等を使わずにスレッドの処理の終了順に依存している ような部分があれば、状況のよってはスレッドの終了順が変わってしまって うまく同期できないケースもあります。 元々、スレッドは行儀よく順番に動作するとは限りませんから うまく同期が取れていないと特定のスレッドばかり処理が進んでしまうケースも あったりします。スレッド絡みの不具合の場合はそういうケースも検討の範囲に 入れたほうが良いと思います。 スレッドのそういった仕様はMSDN上にも記載されていますが、 XPとVistaでこの辺の動作に違いが出てきているようで、 XPでは動いていたのにVistaではうまく行かないケースもあるみたいです。 仕様上は上記のように書かれていたけれど、XPでは実装の関係で偶々うまく 噛み合っていたと言うケースもあると思います。 スレッド絡みで思いつくことといったらこの位でしょうか。 |
1