私はWindowsメッセージを処理するために2つのスレッドを持っています。クライアント領域のキー入力/マウス入力(このスレッドはゲームロジックも処理します)と残りの1つは、ゲームを作成し、DefWindowProc()をブロックしてゲームをフリーズさせるメッセージです。Windows:2つのスレッドがメッセージを処理していますか?
どうすればこの問題を解決できますか?
私はWindowsメッセージを処理するために2つのスレッドを持っています。クライアント領域のキー入力/マウス入力(このスレッドはゲームロジックも処理します)と残りの1つは、ゲームを作成し、DefWindowProc()をブロックしてゲームをフリーズさせるメッセージです。Windows:2つのスレッドがメッセージを処理していますか?
どうすればこの問題を解決できますか?
Codyが書いたのとは逆に、あなたは確かに複数のスレッドからのメッセージを処理できます。しかし、これはカスタマイズ可能なすべてではありません。むしろ、ウィンドウにはスレッド親和性があります。各スレッドは、そのスレッドによって作成されたウィンドウに送信またはポストされたメッセージを受け取ります。ウィンドウのメッセージを他のスレッドに配信する方法はありません。あなたの特定の状況では
、なぜ独自の隠されたウィンドウとメッセージループを持つワーカースレッドを作成していませんか?メインウィンドウがメインスレッドで処理したくないメッセージを受信したときに、それを他のウィンドウにポストすると、そのスレッドはキューに入れられ、ワーカースレッドによって処理されます。
ああ、違うことを暗示するつもりはありませんでした。おそらく私はそれを少し強調した。 UIのないスレッドでUI作業をしようとすると、多くの人が深刻な問題に陥るのを私は見てきました。 –
まさに私が必要なもの – Jonathan
Windowsがすでに提供しているメッセージキューを処理するスレッドが1つだけ必要です。計算上重いものは、CreateThreadで新しいものを作成して別のスレッドにディスパッチする必要があります。あなたが常にこれをやっていると分かったら、そのスレッドを永久にそこに持っていますが、必要なときに作業をするように通知してください。
いいえ、すべてのメッセージを1つのスレッドで処理する必要があります。この1つのスレッドは、ユーザーインターフェイスを制御するスレッドであるため、UIスレッドと呼ばれることがあります。 UI以外のスレッドでUIメッセージを処理しようとすると、問題が発生します。
しかし、一般的な問題は、特定のメッセージに応じて、長時間実行、計算集約タスクを実行するアプリケーションです。コードがメッセージハンドラの内部で実行されているときに、アプリケーションが他のメッセージ(スレッドは一度に1つしか処理できません)を処理することができず、UIが応答しなくなるため、これはうまくいきません。
ソリューションは、別のスレッドをスピンオフ(または2つまたはしかしあなたが必要とする多くの)と、そのスレッドにオフ長時間実行、計算集約タスクを委任することです。単一のUIスレッドでメッセージを処理しますが、メッセージハンドラの内部では、タスクをヘルパースレッドに渡します。 「ワーカースレッド」パターンまたは「バックグラウンドスレッド」パターンと呼ばれることがよくあります。
CreateThread
functionを使用して追加のスレッドを作成できます。サンプルhereが見つかります。この場合
QueueUserWorkItem
functionは単純オプションであるかもしれないように、それが聞こえます。サンプルコード:
DWORD CALLBACK ThreadProc(LPVOID p)
{
HWND hWnd = reinterpret_cast<HWND>(p);
for (int i = 0; i < 100000; ++i)
{
// do whatever
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN: // or whatever message you want to respond to
{
QueueUserWorkItem(ThreadProc, hWnd, WT_EXECUTELONGFUNCTION);
return 0;
}
// process other messages...
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Win32スレッドプールでの読み取りは、hereです。
複数のUIスレッドを持つことはできますが、各ウィンドウはメッセージが配信されるスレッドが1つのみに関連付けられています。 –
'DefWindowProc'は本当に「ブロック」していません...かなり高速です。ブロックする原因となるメッセージの例を挙げられますか? –
既存のデザインをそのまま残しておき、代わりに低速の応答をバックグラウンドスレッドで実行して、ゲームがフリーズしないようにする方がよいでしょう。 –
ウィンドウを移動またはサイズ変更する場合、DefWindowProcはマウスボタンを離すまでブロックします – Jonathan