同じメモリにアクセスしているスレッド(読み取りまたは書き込み)がある場合は、ロックを使用するか、ロックのないデータ構造を使用する必要があります。そうしないと、複数のスレッドが同時にアクセスしているときに、データ構造が破損する(または破損しているように見える)可能性があります。
あなたが指している例は、事前に割り当てられた固定サイズのベクトルを使用しているようです。オーディオスレッドはこのバッファーに書き込んでおり、UIスレッドはそれを読み取っていますが、2つは同期されていません。2つは完全に同時に実行される可能性があるため、UIスレッドには、実際に読み取られているデータについての保証はありません。アップデートNから一部のデータを読み取り、アップデートN+1から一部のデータを読み取る場合があります。一部のデータを見逃したり、一部のデータを2回(またはそれ以上)読み取ったりする可能性があります。これは、オーディオアプリケーションを構築するための堅牢な方法ではありません。視覚化の結果は完全である必要はないため、単純な視覚化アプリには十分に「機能」しますが、記録または再生アプリケーションにはまったく適していません。
オーディオ再生には「リアルタイム」要件があるため、オーディオアプリケーションは(ロックを使用する代わりに)ロックフリーのデータ構造を使用することがよくあります。オーディオバッファに100ミリ秒のサウンドが含まれている場合は、これらのバッファを1秒間に10回満たす必要があります。そうしないと、オーディオの再生が途切れます。別の言い方をすれば、毎回バッファを埋める 期限が100ミリ秒あるということです。
この100ミリ秒の期限を逃す原因となる可能性のあるものはさまざまです。システムがビジー状態である場合、プロセスがスケジュールされない可能性があります。または、ページフォールトにより、ディスク読み取りが原因でプロセスが長時間ブロックされる可能性があります。たとえば、いくつか例を挙げます。ロックを取得しようとしているが、別のスレッドが100ミリ秒を超えてロックを保持している場合、これにより期限を逃してしまいます。これが、ロックの使用がオーディオアプリケーションに悪影響を与える可能性がある理由です。ロックを長時間保持する別のスレッドを使用すると、期限を逃す可能性があります。
ロックフリーのデータ構造では、待機するロックがないため、他のスレッドが進行を停止することはできません。オーディオI/Oの期限を簡単に設定できます。
しかし、ロックフリーアルゴリズムに興奮しすぎる前に、それらがはるかに微妙であり、ロックよりも正しく使用するにははるかに多くの専門知識が必要であることを知っておく必要があります。基本的に、この分野の専門家でない場合は、ロックフリーアルゴリズムを自分で作成しようとしないでください。おそらく、いくつかのロックフリーアルゴリズムの実装を備えた優れたオープンソースライブラリがあります。私は最近見ていません。
ただし、他の考えられる遅延の原因を回避するためにオーディオスレッドにも細心の注意を払っていない限り、ロックフリーアルゴリズムを使用するために必要な余分な作業は多かれ少なかれ無駄になることに注意してください。具体的には:
オーディオスレッドはメモリを使用してはいけませんmalloc()(free()ほとんどのmalloc / free実装は内部でグローバルロックを取得します)
オーディオスレッドによってアクセスされるメモリがページアウトされていないことを確認する必要があります(例mlock():)
I / O呼び出しがブロックされる可能性があるため、オーディオスレッドはサウンドカード以外のI/Oを実行してはなりません。
非常に勤勉でこれらすべての手順を実行しているのでない限り、他のスレッドと共有されるデータにロックを使用することもできますが、ロックが非常に短時間保持されるようにしてください。たとえば、ロックを保持したままUIスレッドでmalloc()/ free()を実行したり、システムコールをブロックしたりしないでください。