3

わかりました、問題を説明します。私はClanLIBというライブラリを使用しています(私の選択ではありません)。そのライブラリ、SEEMLY(ソースを読んでもわからない)は、サウンドを処理するスレッドを作成します。

バッファが空の場合、このスレッドは、より多くのデータを取得しようとします。通常、サウンドカードがバッファの終わりに到達する前に、データ生成ライブラリが遅すぎて追加のデータを提供できない場合、アンダーランが発生します。

そこで、バックグラウンドでサウンドを生成し続ける独自のスレッドを追加しました。

これはうまくいきましたが、私自身のスレッドが時々あまりにも多くの CPU 時間を乗っ取り、他のすべてをフリーズさせました。それを修正するために、条件付き待機を追加しました。

バッファーがいっぱいになると条件付き待機が発生し、ClanLIB がさらにデータを要求すると、待機が通知され、バッファー書き込みスレッドが再開されます (再びいっぱいになるまで)。

私の問題は、この条件付き待機、ClanLIB サウンド スレッド、および独自の音楽スレッドを追加したため、アプリケーションの残りの部分がフリーズしている間に音楽を再生して「暴走」することがあります。

それを引き起こすのは、どのような奇妙な状態でしょうか?

疑似コード:

//main thread (that get frozen)
start_sound_thread();
do_lots_of_stuff();
quit();

//Sound Thread:

While(true)
{
    play(buffer);
    if(buffer_empty)
    {
         mutex.lock()
         buffer = buffer2;
         if(buffer2_full)
         {
             signal(cond1);
             buffer2_full = false;
         }
         mutex.unlock()
    }
}

//Music Library Thread:

while(true)
{
    mutex.lock()        
    if( check_free_space(buffer2) == 0)
    {
        buffer2_full = true;
        condition_wait(cond1);
    }
    write_music(buffer2);
    mutex.unlock()
}
4

4 に答える 4

1

ミューテックスゾーン内であまりにも多くのことを行っています-cond1信号でデッドロックしている可能性があります。ロック領域内で行うことはできるだけ少なくする必要があります。そうするほど、デッドロックが発生するリスクが高くなります。また、信号の送信を保護するミューテックス内の信号を絶対に待つべきではありません。待っていると、送信されることはありません-condition_waitはmutexオブジェクトのブロックを解除していませんが、どうすればそれを知ることができますか?

「条件付き待機の追加によって解決された」は、デッドロックにつながる競合状態が発生したことを示す強力な指標です。ロジックの実行タイミングが何らかの理由で変更された直後、たとえば別のアプリが原因で、問題が解決されていません。が実行されている場合、デッドロックが戻る可能性があります。

于 2010-08-13T20:21:48.917 に答える
1

私もプロジェクトにclanlibを使用していますが、サウンドにはOpenALを使用しています。バッファのフィードなどでも同じように動作するようです。

私はサウンド用に別のスレッドも使用していますが、私の解決策は、バッファへのフィードを試行するたびに固定のスリープ期間を追加することでした。シンプルでかなり頑丈そうです。そして、ロックは必要ありません;)

于 2010-09-21T10:44:34.197 に答える
0

私は実際、問題が何であったかわかりません、それは偶然に修正されました...

関連する問題がありました。これは、スレッドを削除するときの競合状態が原因でした...いくつかのコードを移動しました (何も再コーディングする必要さえありません)。これで完全に安定しました!(まあ、まだアンダーランがありますが、今ではよりまれです)

于 2010-08-30T02:37:50.567 に答える
0

ClanLib ゲーム SDK を使用している場合、それは十分に確立され、テストされ、サポートされている SDK です。気分を害するつもりはありませんが、あなたは認められた初心者であるため、問題は彼らのコードよりもあなたのコードにある可能性が高くなります.

このように十分に確立されたライブラリがアンダーランを起こすとは信じがたいと思いますadded my own thread, that keeps generating sound on the background。私がこれを言うのは、あなたが間違ったアプローチを取っていると思われるためです.ClanLibで解決策を見つけることができれば、スレッドは必要なく、解決する必要なく問題は解決します.

コードを投稿したのはgooです、ありがとう。私は行って、今それを見ます。

最後に、私と同じように SO の大ファンなので、最初に公式のClanLib フォーラムで質問したほうがよいのではないでしょうか?


編集:アンダーランであると確信できる理由は何ですか?私はまだそれを信じるのが難しいと思いますが、あなたのプログラムでそれを検出することができれば、sleep()サウンドを生成するのではなく、なぜそうしないのですか? (どのくらい眠るの? 生成する音の量をどのように知るのですか? また、生成された音は「実際の」音と干渉しませんか?)

于 2010-08-11T23:53:01.057 に答える