Безопасно ли использовать Bools для синхронизации нескольких потоков?
-
10-10-2019 - |
Вопрос
Я пишу аудио -приложение с несколькими потоками, производящими звук, и один поток, который смешивает звуки и отправляет их на звуковую карту. Я пробовал несколько способов синхронизации потоков «правильный» способ, включая сигналы и безопасные очереди потока, но они были слишком медленными. Итак, теперь я использую 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;
}
}
Потребитель выглядит так (называется из отдельного потока 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;
}
Решение
Нет, это не совсем безопасно, но большую часть времени вам повезло ;-) Вы должны использовать Блокируется Методы для доступа к Bool.
Другие советы
Насколько я знаю, модель памяти .NET не гарантирует, что изменения переменной, сделанной в одном потоке, будут видны в другом потоке. Вам нужна память барьер там. Самый простой (хотя и не самый эффективный) способ организации, используя использование lock
или же Interlocked
методы
Кстати, занятое ожидание - не лучший способ для достижения вашей цели. Может быть, вы хотите перейти на Производитель-потребитель модель с соответствующей переменной условием (Monitor
S в C# PALLANCE) Использование?