2011-12-28 45 views
3

データ取得用と表示用の2つのスレッドがあります。不必要な同期を避けるためです。書き込みが(他のバッファに、バッファのデータスレッドスイッチを完了すると表示スレッドがバッファ2 マルチスレッドアプリケーションでダブルバッファリングを同期する方法

  • を読みながら

    1. データのスレッドがバッファ1を書いている:私は次のようにダブルバッファ(又はページフリッピング)を使用しバッファ2)、新しいページの書き込みを開始します。
    2. 読み取りの場合、バッファが書き込みの途中にある場合、表示スレッドは他のバッファから読み込みます。

    実際にはうまくいくことがありますが、時には100フレームごとに1回表示されます。これは、まだ競合状態があることを意味します。

    このように、このダブルバッファリングの最小限の(効果的な)同期を実装するにはどうすればよいですか?疑似アルゴリズムで十分です。

  • +0

    あなたのGUIライブラリがあなたのために行うのでなければ、ビデオカードのリフレッシュ信号に関してダブルバッファリングも同期させる必要があります。それ以外の場合は、ディスプレイを再描画すると同時にモニタが更新された場合にも、「引き裂き」が発生する可能性があります。 –

    答えて

    1

    次の2つのセマフォでこれを行うことができます。

    ここでグラフィックスレンダリングと転送を同期させるためにメッセージパッシングを使用して、いくつかのコードです。これはProducer/Consumer問題のバリエーションです。私が提供したリンクの疑似コード。

    +0

    意味があります。ありがとう! –

    +0

    私はセマフォを使用しませんでしたが、ロックなしで簡単なキュー構造を使用しました。それは完璧に働いた。 –

    +0

    Hmm。私はあなたが問題を解決したかどうかは疑問だ。競合状態の可能性を減らしたかもしれませんが、同期プリミティブがなければ、100%確実な解決策を持つことはできません。 – Miguel

    1

    どの言語、プラットフォーム、(必要な場合)グラフィックAPIを使用していますか?

    疑似アルゴリズムで十分です。

    状況に応じてさまざまなアプローチがありますが、具体的にする必要があります。たとえば、クリティカルセクションを宣言して、スレッド1がスレッド2の読み取り中に書き込みを待つようにすることができます。しかし、それをしない理由があります。

    重要なセクションで作業するのではなく、描画スレッドを起動するメッセージパッシングで作業するだけで済みます。したがって、実際には言語、プラットフォーム、グラフィックスAPIに大きく依存しています。

    DataAcquisitionThread.Run() { 
        ProcessData(); 
        Wait(message); 
        DrawToBackBuffer(); 
    } 
    
    DisplayThread.Run() { 
        Wait(message); 
        SwapBuffer(message.bufferNumber); 
        Render(buffer); 
        SendMessage(message.defaultMessage()); 
    } 
    
    +0

    @Paul:メッセージの受け渡し方法を追加しました。私は、スレッドスケジューリングシステムを持たないシステムでオーディオバッファを同期させるために使用しました(代わりに、メッセージを送信すると実行中のスレッド/プロセスをスワップします)。 –

    関連する問題