E 'sicuro da usare Caccio per sincronizzare più thread?
-
10-10-2019 - |
Domanda
Sto scrivendo un'applicazione audio che ha più thread produzione del suono e un filo che mescola i suoni e li invia alla scheda audio. Ho provato diversi modi di fili sincronizzazione il modo 'giusto' inclusi i segnali e filo code sicure ma erano tutti troppo lento. Così ora io uso un bool per ciascun produttore per indicare se la sua coda è piena. Sembra funzionare molto bene (5ms latenza per 32 fili), ma è sicuro di farlo in questo modo?
class PlayThreadParameters
{
public Queue<Samples> queue;
public bool isOutputQueueFull;
}
I produttori simile a questa:
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;
}
}
Gli sguardi di consumo come questo (chiamato da un thread separato da 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;
}
Soluzione
No it is not completely safe, but you might get lucky most of the time ;-) You should be using the Interlocked methods to access the bool.
Altri suggerimenti
As far as I know, the .NET memory model doesn't guarantee that the changes of a variable made in one thread will be visible in another thread. You need a memory barrier there. The simplest (though not the most efficient) way to organize that is by using lock
or Interlocked
methods.
By the way, busy waiting is not the best method to achieve your goal. Maybe you'd like to switch to the producer-consumer model with appropriate condition variable (Monitor
s in C# parlance) usage?