DOONです。いつもお世話になっています。開発環境は、windowsXP ServicePack2 VB.NET 2005です。シンプルな質問です。VB.NET 2005で、windowsのexeを一つ作りました。なにもコントロールは貼っていません。ビルドでReleaseモードでEXEを作成しました。このEXEをタスクマネージャーでみるとスレッド数が4となっています。VB6のexeだとスレッド数はもちろん1です。びっくりです。こっちがスレッドを作成していないのに!!マルチスレッドのEXEが自動で作成されるのでしょうか?問題は、今タイマーで動かしているプログラムがあって、どうも、それがマルチスレッドぽい動きをするので気になっているのです。詳しい方よろしくお願いします。
> このEXEをタスクマネージャーでみると> スレッド数が4となっています。そんなもんです。> こっちがスレッドを作成していないのに!!> マルチスレッドのEXEが自動で作成されるのでしょうか?自分が管理するのは(作らない限り)一つだけなんで気にする必要は無いです。> 問題は、今タイマーで動かしているプログラムがあって、> どうも、それがマルチスレッドぽい動きをするので> 気になっているのです。タイマしだいで確かに別スレッドで動くものもありますが、多分マルチスレッドでは動いてません。なにか不審な点があれば具体的に質問をお願いします。
> > このEXEをタスクマネージャーでみると> > スレッド数が4となっています。> そんなもんです。そうですか、びっくりしました。> > > こっちがスレッドを作成していないのに!!> > マルチスレッドのEXEが自動で作成されるのでしょうか?> 自分が管理するのは(作らない限り)一つだけなんで気にする必要は無いです。それが聞けると安心です。> > 問題は、今タイマーで動かしているプログラムがあって、> > どうも、それがマルチスレッドぽい動きをするので> > 気になっているのです。> タイマしだいで確かに別スレッドで動くものもありますが、多分マルチスレッドでは動いてません。> なにか不審な点があれば具体的に質問をお願いします。すいません。system.windows.form.timerを画面に貼り付けて、一秒周期で動かしています。timer_timer{ //SQLサーバーにつなぎにいく //失敗したら、シーケンシャルファイルに失敗した時刻を書き込む}としています。ずーっと、SQLサーバーにつながらないというテストをしています。すると、シーケンシャルファイルないに同じ時刻が立て続けに三回ぐらい連続で書き込まれています。SQLサーバーにつなぎにいくのは失敗したらmsecで帰ってくるのですがたまに、5秒ぐらい帰ってこないときがあります。この5秒のあとに、シーケンシャルファイル内に同じ時刻が連続して書き込まれるときがあります。なので、その5秒の間にタイマーイベントが増えていっているのでは?と思ったのですが、シングルスレッドのはずなので、それはありえないと考えました。そして、何もないプログラムを作成するとスレッド数が4こなので驚いたというわけです。解決策としてはtimer_timer{ //最初にタイマーを殺す timer.enabled = false //各処理・・・・ //最後にタイマーを復活 timer.enabled = true}こうすると、問題がなかったのです。ただ、この動きを理解したいのです。以上、よろしくお願いします。
むしろシングルスレッドだからこその挙動だと思いますよ。マルチスレッドの場合、5 秒かかってる処理の間に次の処理が走り順番崩壊、ってことになります。Windows のウィンドウシステムはメッセージが中心になって動いています。入力や再描画要求などが発生すると、メッセージが発行されアプリケーションが持つメッセージキューに蓄えられます。アプリケーションはメッセージキューから順次メッセージを取り出し、そのメッセージに対応する処理を行います。System.Windows.Forms.Timer は WM_TIMER メッセージを使ったタイマです。WM_TIMER は OS から定期的に送信され、メッセージキューに追加されます。このとき、今何もやってないならメッセージが来た直後にメッセージを取り出して処理を行えますが、今忙しいならしばらくメッセージキューからメッセージを取り出すことができず、未処理のメッセージがどんどん溜まっていくことになります。当然、WM_TIMER も同様に溜まっていくわけで、忙しい処理が終わった後、どっさり積まれた WM_TIMER を続けざまに処理することになります。
DOONです。返事ありがとうございます。勉強になります。> むしろシングルスレッドだからこその挙動だと思いますよ。そうなのですか。> System.Windows.Forms.Timer は WM_TIMER メッセージを使ったタイマです。WM_TIMER は OS から定期的に送信され、メッセージキューに追加されます。理解できました。ありがとうございました。残りの3つのスレッドって、何をしてるのでしょうね?改めで現在作成中のプログラムを見るとスレッド数が23とかでびっくり。シングルスレッドのプログラムなのに・・・。vb6からの乗り換えで、びっくりしています。
> VB.NET 2005で、windowsのexeを一つ作りました。> なにもコントロールは貼っていません。> ビルドでReleaseモードでEXEを作成しました。> このEXEをタスクマネージャーでみると> スレッド数が4となっています。.NET Frameworkのスレッド数ではなく,OSのスレッド数をカウントしたのですよね。それであれば,何ら問題ないでしょう。CLRは裏でJITやGCのためのスレッドを用意しています。Process Explorerで見ると,.NETの物理スレッド数,.NETの論理スレッド数,OSのスレッド数の全てが異なることもあり得ます。
DOONです。返事ありがとうございます。> > .NET Frameworkのスレッド数ではなく,OSのスレッド数をカウントしたのですよね。そうなんですか、普通にタスクマネージャーでスレッド数を表示しただけです。OSのスレッド数というのがあるのですか?勉強になります。OSのスレッド数というのを調べてみますね。VB6だと、そこでもスレッド数が1だったので、あせっていました。> CLRは裏でJITやGCのためのスレッドを用意しています。JITというのをはじめて聞いたので、調べました。勉強になります。ngen.exeでしたっけ。初めて知りました。> Process Explorerで見ると,.NETの物理スレッド数,.NETの論理スレッド数,> OSのスレッド数の全てが異なることもあり得ます。三連休なので、週明けに調べてみたいと思います。ありがとうございます。
DOONです。Process Explorerでいま、みました。やはりスレッド数は4つですね。OSのスレッド数とかって、どこで見れるのでしょうか?Select ColumnsのStatus Barでチェックするということでしょうか?これだと、全体の表示になってしまいます。以上、よろしくお願いします
> Process Explorerでいま、みました。> やはりスレッド数は4つですね。> OSのスレッド数とかって、> どこで見れるのでしょうか?何か勘違いされているようですが,OSのスレッド数というのは,Create Thread API等を使って作成された,OSが管理するスレッドの数のことです。Process Explorer上では,プロセスのプロパティでThreadsタブに出てきます。# タスクマネージャで表示されるスレッド数は,上記のこと。.NETが管理しているスレッドは,.NETタブに出てきます。.NET Performance Objectsに.NET CLR LocksAndThreadsを選択すると,いくつかの表示があるはずです。.NET用の実行ファイルは,.NET Frameworkという仮想マシン上で動きます。タスクマネージャで見ることのできるスレッド数は,あくまで仮想マシンを動作させるのに必要なスレッド数であって,仮想マシンに存在するスレッド数や,ユーザープログラムが利用しているスレッド数ではないことに注意してください。
DOONです。返事ありがとうございます。質問ばかりですいません。> 何か勘違いされているようですが,OSのスレッド数というのは,> Create Thread API等を使って作成された,OSが管理するスレッドの数のことです。> Process Explorer上では,プロセスのプロパティでThreadsタブに出てきます。> # タスクマネージャで表示されるスレッド数は,上記のこと。そうですよね。これが4つって出たので私はCreateThreadしていないのに・・・。と思ったのです。> .NETが管理しているスレッドは,.NETタブに出てきます。> .NET Performance Objectsに.NET CLR LocksAndThreadsを選択すると,> いくつかの表示があるはずです。場所が分かりました。ありがとうございます。of current logical threadsが2ですね。> .NET用の実行ファイルは,.NET Frameworkという仮想マシン上で動きます。> タスクマネージャで見ることのできるスレッド数は,> あくまで仮想マシンを動作させるのに必要なスレッド数であって,> 仮想マシンに存在するスレッド数や,> ユーザープログラムが利用しているスレッド数ではないことに注意してください。としますと、私が作成している、なにもコントロールを貼っていないプログラムにおいて、シングルスレッドだと表示する方法はない!ということですね。変な質問ですいません。問題は解決しているのですが、気になると、やはり気になってしまいまして。今後、マルチスレッドのプログラムを作成した時にあのスレッドがちゃんと死んだかなーというのをタスクマネージャーでみたりする時を考えると・・・。以上、よろしくお願いします。