過去の投稿記事 new!
・【画像】漫画でわかる外国人参政権
・東京電力のHPで停電状態が確認できたり(サービス再開!)
・戦国時代 ~ 江戸時代の徳川家康が熱かった
・vaio のバッテリは寿命が短いような気がする
・話題の Western Digital 製 WD20EARS を購入した
・C01LC をビックカメラで買ってきた
・2025年には空中都市が現実化?!
・【動画】わかりやすい「宇宙ひも理論」
・今世紀には「富士山噴火」「東海連動地震」「首都圏直下型地震」か?
・滅びた町、南浜町が Googleストリートビューで見れる

【 amazon 送料無料キャンペーン 】

バックリンクはご自由にどうぞ!     http://mfsocket.blogspot.com/feeds/posts/default?alt=rss リンク集 / ログイン

2010/04/26
CreateWindow はメインスレッドのみ有効

 
きちんと検証したこと無かったのですが、今までの経験から避けていた
 
別スレッドでのウィンドウ作成
 
は CreateWindow() の仕様上、対応していなかったみたい。
 
これだけだと語弊があるので言い直しますが、
 
GetMessage() / DispatchMessage() /  TransalteMessage()
 
を実装していないスレッド上で、CreateWindow() を行っても、メッセージループ処理
が行われない為、フリーズするということです。
 
メインスレッド以外でウィンドウを作成する場合は、そのスレッドでもメッセージループ
を実装してやらないとダメ。
 
昔、DirectX の初期化を別スレッドでやろうとして、一部どうしてもうまくいかない時が
あったのですが、それもこれ関連かも。
 
DestroyWindow() がメインスレッド以外では無効というのは昔から知っていたのですが、
それもメッセージループのと関係していたってことか。
 
 
あと非常にハマりやすいのが、
 
SetDlgItemText() や SetDlgItemInt() や SetWindowPos()
 
などは全部 SendMessage() で行われる為、別スレッドにてロックオブジェクトを使い
ロックした状態で Setxx() を呼ぶコードがある場合は、
 
メインスレッドでロックオブジェクトを使ってるシーン(関数)に入ろうとするとフリーズ…
いうよりデッドロックが、起こりえます。
 
 
ウィンドウメッセージは、あくまでメインスレッド(CreateWindowをしたスレッド)から
呼び出されるという点が重要ですね。
 
デッドロックするシーンがあるか紙に書いてみると、当たり前のようにあった。
 
そもそも Set XXXX 系の関数をロックオブジェクトをロックしたまま呼び出すコードは、
危険な可能性は秘めていると痛感しています。
 
デッドロックするわけないだろと思ってたのですが、SendMessage() を利用している関数
という意識が外れると、中々気づかないものですね。
 

0 コメント:

  • コメントには <b>, <strong>, <em>, <i>, <a> など一部の HTML タグを使用できます。