使用 bool 来同步多个线程是否安全?

发布于 2024-10-02 14:38:15 字数 1443 浏览 1 评论 0原文

我正在编写一个音频应用程序,该应用程序具有多个产生声音的线程和一个混合声音并将它们发送到声卡的线程。我尝试了几种以“正确”方式同步线程的方法,包括信号和线程安全队列,但它们都太慢了。所以现在我为每个生产者使用一个布尔值来指示其队列是否已满。它似乎工作得很好(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;
    }
}

消费者看起来像这样(由 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;
        }

I'm writing an audio application that has multiple threads producing sound and one thread that mixes the sounds and sends them to the sound card. I've tried several ways of synchronizing threads the 'right' way including Signals and thread safe queues but they were all too slow. So now I use a bool for each producer to indicate whether its queue is full. It seems to work very well (5ms latency for 32 threads) but is it safe to do it this way?

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

The producers look like this:

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

The consumer looks like this (called from a separate thread by 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;
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

走过海棠暮 2024-10-09 14:38:15

据我所知,.NET 内存模型并不能保证一个线程中对变量所做的更改在另一个线程中可见。你需要一个内存屏障。最简单(尽管不是最有效)的组织方法是使用 lockInterlocked 方法。

顺便说一句,忙碌的等待并不是实现目标的最佳方法。也许您想切换到具有适当条件变量(Monitor(用 C# 的说法)用法?

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?

忘年祭陌 2024-10-09 14:38:15

不,它并不完全安全,但大多数时候您可能会很幸运;-)您应该使用 访问 bool 的互锁方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文