Question

J'écris une application audio qui a plusieurs threads produisant des sons et un fil qui mêle les sons et les envoie à la carte son. J'ai essayé plusieurs façons de synchroniser des fils comme « droit », y compris les signaux et le fil de sécurité des files d'attente, mais ils étaient trop lents. Alors maintenant, j'utilise un bool pour chaque producteur pour indiquer si sa file d'attente est pleine. Il semble fonctionner très bien (5ms de latence pour 32 threads), mais est-il sûr de le faire de cette façon?

class PlayThreadParameters
{
    public Queue<Samples> queue;
    public bool isOutputQueueFull;
}

Les producteurs ressemblent à ceci:

  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;
    }
}

Les regards des consommateurs comme celui-ci (appelé à partir d'un thread séparé par 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;
        }
Était-ce utile?

La solution

Non, ce n'est pas complètement sûr, mais vous pourriez avoir de la chance la plupart du temps ;-) Vous devez utiliser la balise Interlocked les méthodes d'accès à l'booléens.

Autres conseils

Pour autant que je sache, le modèle de mémoire .NET ne garantit pas que les changements d'une variable faite dans un thread sera visible dans un autre thread. Vous avez besoin d'une mémoire barrière là. Le plus simple (mais pas le plus efficace) façon d'organiser qui est en utilisant des méthodes de lock ou Interlocked.

Par ailleurs, l'attente est occupé pas la meilleure méthode pour atteindre votre objectif. Peut-être que vous souhaitez passer à la modèle producteur-consommateur avec la variable condition appropriée (Monitors en C # langage ) utilisation?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top