ブールを使用して複数のスレッドを同期するのは安全ですか?
-
10-10-2019 - |
質問
サウンドを生成する複数のスレッドとサウンドを混ぜてサウンドカードに送信する1つのスレッドを備えたオーディオアプリケーションを書いています。私は、信号やスレッドセーフキューを含む「正しい」方法でスレッドを同期する方法をいくつか試しましたが、それらはすべて遅かったです。そのため、プロデューサーごとにブールを使用して、キューがいっぱいかどうかを示します。それは非常にうまく機能しているようです(32スレッドの場合は5msレイテンシ)が、このようにするのは安全ですか?
class PlayThreadParameters
{
public Queue<Samples> queue;
public bool isOutputQueueFull;
}
プロデューサーは次のように見えます:
public void PolyPlayThread(object o)
{
var playThreadParameters = (PlayThreadParameters)o;
while (isPlaying)
{
while (playThreadParameters.isOutputQueueFull)
{
if (!isPlaying)
return;
Thread.Sleep(1);
}
... //fill output queue
playThreadParameters.isOutputQueueFull = true;
}
}
消費者はこのように見えます(Naudioによって別のスレッドから呼ばれます):
public override int Read(byte[] array, int offset, int count)
{
for (int v = 0; v < playThreadParameters.Length; v++)
while (!playThreadParameters[v].isOutputQueueFull)
{
if (!isPlaying)
return 0;
Thread.Sleep(1);
}
... //mix the samples from the outputqueues
for (int v = 0; v < playThreadParameters.Length; v++)
playThreadParameters[v].isOutputQueueFull =false;
return count;
}
解決
いいえ、それは完全に安全ではありませんが、ほとんどの場合幸運を得るかもしれません;-)あなたは インターロック ブールにアクセスする方法。
他のヒント
私の知る限り、.NETメモリモデルは、あるスレッドで作成された変数の変更が別のスレッドで表示されることを保証しません。メモリが必要です バリア そこの。使用することによって、最も単純な(最も効率的ではありませんが)整理する方法 lock
また Interlocked
方法。
ちなみに、忙しい待機はあなたの目標を達成するための最良の方法ではありません。たぶんあなたはに切り替えたいです プロデューサー消費者モデル 適切な条件変数(Monitor
s c#parlance)使用法?
所属していません StackOverflow