我正在编写一个音频应用程序,该音频应用程序具有多个线程产生声音和一个线程,该线程将声音混合并将其发送到声卡。我已经尝试了几种方式将线程同步的“正确”方式,包括信号和线程安全队列,但它们都太慢了。因此,现在我使用一个布尔供每个生产商指示其队列是否已满。它似乎运行良好(32个线程的延迟5毫秒),但是这样做安全吗?

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;
        }
有帮助吗?

解决方案

不,这不是完全安全的,但是您大部分时间都可能会很幸运;-)您应该使用 互锁 访问布尔的方法。

其他提示

据我所知,.NET内存模型不能保证在另一个线程中可见一个线程中的变量的更改。您需要记忆 障碍 那里。最简单(尽管不是最有效的)组织方法 lock 或者 Interlocked 方法。

顺便说一句,忙碌的等待不是实现目标的最佳方法。也许您想切换到 生产者消费者模型 有适当的条件变量(Monitors in c#callance)用法?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top