2

Windows クリティカル セクションにキューの概念はありませんか?

専用スレッドに次のレンダリング ループがあります。

while (!viewer->finish)
{
  EnterCriticalSection(&viewer->lock);
  viewer->renderer->begin();
  viewer->root->render(viewer->renderer);
  viewer->renderer->end();
  LeaveCriticalSection(&viewer->lock);
}

メイン スレッドはメッセージ処理を行い、マウス イベントを処理するときに同じクリティカル セクションに入ろうとしますが、何らかの理由で、メイン スレッドが最終的に入る前にレンダリング スレッドをさらに 1000 回 (約 10 秒) 実行します。クリティカルセクション。これを引き起こしているのは何ですか - セクションに入る「キュー」がなくても、私の場合のように 99.9/0.1 ではなく、50/50 のようにすべきではありませんか? 両方のスレッドの優先度は 0 です。

そして、そのようなキューを追加する良い方法は何ですか? bDoNotRenderAnything のような単純なフラグで十分でしょうか?

編集:私の場合の解決策は、メッセージハンドラーがクリティカルセクションへのアクセスを必要とするたびに設定され、それを使用した後にリセットされるイベントオブジェクトを追加することでした(ブール変数もおそらく機能します)。変数/イベントが設定されている場合、レンダラーはセクションに入りません。このようにして、メッセージ ハンドラーは複数回のレンダリングの繰り返しを待つ必要がなくなります。

4

4 に答える 4

3

クリティカル セクションで待機しているスレッドが、先着順でクリティカル セクションを取得しない ( MSDN )

ほとんどの場合、ワーカー スレッドがロックを所有します。これは、ロックを解放した直後にワーカー スレッドが再ロックされるためです。そのため、他のスレッドが解放されたときにロックを解除してキャッチする時間はあまりありません。

于 2013-04-04T08:07:59.850 に答える
1

MSDNによると

There is no guarantee about the order in which waiting threads 
will acquire ownership of the critical section.

そのため、スレッドが実行される順序は不明です。そして、あなたのかなり短い場合

viewer->renderer->begin();
viewer->root->render(viewer->renderer);
viewer->renderer->end();

シーケンスがオーバーを取り戻すことができCriticalSectionた場合、これが発生する可能性があります。

于 2013-04-04T08:07:02.983 に答える
0

レンダリング ループでSwitchToThread呼び出しを使用してクイック フィックスを試すことができますが(特定の回数の反復の後)、十分な解決策になるとは思えません。

于 2013-04-04T08:25:26.467 に答える