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;
        }
È stato utile?

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 (Monitors in C# parlance) usage?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top