Безопасно ли использовать bools для синхронизации нескольких потоков? - PullRequest
4 голосов
/ 15 ноября 2010

Я пишу аудио-приложение, которое имеет несколько потоков, производящих звук, и один поток, который смешивает звуки и отправляет их на звуковую карту.Я пробовал несколько способов синхронизации потоков «правильным» способом, включая сигналы и очереди, безопасные для потоков, но все они были слишком медленными.Поэтому теперь я использую bool для каждого производителя, чтобы указать, заполнена ли его очередь.Кажется, он работает очень хорошо (задержка 5 мс для 32 потоков), но безопасно ли это сделать таким образом?

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

Потребитель выглядитвот так (вызывается из отдельной темы Наудио):

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

Ответы [ 2 ]

5 голосов
/ 15 ноября 2010

Насколько я знаю, модель памяти .NET не гарантирует, что изменения переменной, сделанные в одном потоке, будут видны в другом потоке. Вам нужна память барьер там. Самый простой (хотя и не самый эффективный) способ организации - использование методов lock или Interlocked.

Кстати, занятое ожидание - не лучший способ для достижения вашей цели. Может быть, вы хотите перейти на модель производитель-потребитель с использованием соответствующей переменной условия (Monitor s на языке C #)?

4 голосов
/ 15 ноября 2010

Нет, это не совсем безопасно, но большую часть времени вам может повезти ;-) Для доступа к bool вы должны использовать методы Interlocked .

...