- - PR -
C#のLock処理について
投票結果総投票数:8 | |||
---|---|---|---|
Windows | 8票 | 100.00% | |
|
投稿者 | 投稿内容 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-03-27 13:58
お世話になっております。 このロックの仕方について、いろいろ調べましたが、下記の記事では説明がありますがロック出来ないケースは中々浮かんできませんので、ニ三ご教授いただけませんか? http://msdn.microsoft.com/msdnmag/issues/03/01/NET/ [ メッセージ編集済み 編集者: Bob 編集日時 2006-03-27 14:03 ] | ||||||||||||||||||||||||
|
投稿日時: 2006-03-27 14:30
多分大嘘ついてしまったかも…。
ロックできないケースではなく、すぐにデッドロックしてしまうでした…。すみません。 #そんなケースがあったような気がしたんですが脳から出てこない…。 なんでデッドロックしてしまうかと言うと、this ではロックするものが大きすぎて、違う箇所で違う目的で同じ参照をロックしてしまう可能性を秘めているからです。 _________________ 囚人のジレンマな日々 | ||||||||||||||||||||||||
|
投稿日時: 2006-03-27 21:46
皆様から多くの指摘を頂き、ありがとうございます。
開示内容について、Jittaさんの仰るとおりですが、うまく出来なかった点について反省しております。一応、現時点調査してことをご報告いたします。
Thread及びBeginInvoke両方とも下記の方法で試した結果、現状スレッドがGCに回収されたことがありませんでした。
意図としては、ProcessA と ProcessBの結果は順不同で、受け取った結果が処理されないことは依然原因不明です。
この点について、当方はかなり改善する余地があります。現状、大抵
のやり方でロックしているし、スレッド数もかなり多いので、タイミングにより何か影響している可能性もあります(BeginInvokeで生成することが多い)。
大変申し訳ありません。やはりどこかで書き間違ったかもしれません。ProcessBだけが実行されることがなく、両者とも実行完了した通知を受けた場合のみ、AnotherMethod が実行される。いま、両者のEventハンドラで通知を受けたことが確認出来たが、AnotherMethodが実行されない原因を追求しているところです。 | ||||||||||||||||||||||||
|
投稿日時: 2006-03-27 22:11
これ→Threading Tips: Never Lock a Value Type. Never Lock "This".
Google 検索: lock "this" (this を2重引用符で囲む) | ||||||||||||||||||||||||
|
投稿日時: 2006-03-27 22:23
私も確認しました。 これにより、当初疑われていた、GC によってスレッドが破棄されることはない、といえると思います。 # 不思議だ。何で Dispose しなくていいんだろう? # スレッドハンドルはどうなっちゃうんだろう?
ん〜ん?でも、eventID 0 の時は、A → B ですよね?そういう風にコーディングされていますよね? おそらく、eventID 3〜8 のどれかで、B が起動されるのかもしれません。 で、4も関係するのですが、何かひとつの処理が実行されていれば、ほかの呼び出しはすべてブロックされています。であれば、スレッドを使う意味がないのでは?と思います。
まず、呼び出しタイミングで、スレッド ID と、なんのための呼び出しかを記録できるようなコードを追加してください。 そして、タスクマネージャにスレッド数が見られるように列を追加し、スレッドの生成と終了のタイミングを見てみてください。 あと、フラグを false にするタイミングはないですか? おそらく、ブロックされているスレッドが解除される順番は、期待できないと思います(lock の前後にスレッド ID をログにはき出せば確認できます)。このため、順番的には A も B も true になっているのに、false する呼び出しが先に処理され、結果的に実行されていないのかもしれません。 | ||||||||||||||||||||||||
|
投稿日時: 2006-03-27 23:11
マネージスレッドはマネージ資源だからでは? # ↑だけ見て書いてるので、間違っていたらごめんなさい。 | ||||||||||||||||||||||||
|
投稿日時: 2006-03-28 00:25
ありがとう御座います。 何故か、文書が開けないみたいですが。。。 開けました。大変参考になりました。 ただ、一つ疑問になるのは、下記の例では異なるスレッドでlockFunc1()とlockFunc2()が呼ばれたら、お互いにロックすることが全くないと思います。そうすると、「ロックの対象となるオブジェクトが全く同じものではないとロックが機能しない」との認識は正しいでしょうか?
[ メッセージ編集済み 編集者: Bob 編集日時 2006-03-28 09:24 ] | ||||||||||||||||||||||||
|
投稿日時: 2006-03-28 09:16
自分の認識だと、BeginInvokeで生成されThreadのハンドルはプロセス毎のThreadPoolにて管理され、決まったタイミングで開放されるのではと思います。 |