Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在音频流应用程序中高效使用fifo_Multithreading_Synchronization_Signal Processing_Fifo - Fatal编程技术网

Multithreading 在音频流应用程序中高效使用fifo

Multithreading 在音频流应用程序中高效使用fifo,multithreading,synchronization,signal-processing,fifo,Multithreading,Synchronization,Signal Processing,Fifo,我有一个音频dsp应用程序,它使用线程池以比实时快得多的速度生成输出。这是为了在游戏中使用,音频流必须具有相当低的延迟。每个完成的缓冲区都会在主混合线程中结束,我需要从主混合线程将其交付给应用程序程序员。我想我可能在主类中有一个read_samples方法,它接受一个缓冲区指针和一些要读取的样本,并返回实际读取的样本数 我正在研究一种无锁fifo,即boost.lockfree中的单生产者/单消费者队列。我目前的设计目标如下: 非常重要的是,数据从fifo中输入和输出 很快,所以我们希望尽可能少

我有一个音频dsp应用程序,它使用线程池以比实时快得多的速度生成输出。这是为了在游戏中使用,音频流必须具有相当低的延迟。每个完成的缓冲区都会在主混合线程中结束,我需要从主混合线程将其交付给应用程序程序员。我想我可能在主类中有一个read_samples方法,它接受一个缓冲区指针和一些要读取的样本,并返回实际读取的样本数

我正在研究一种无锁fifo,即boost.lockfree中的单生产者/单消费者队列。我目前的设计目标如下:

  • 非常重要的是,数据从fifo中输入和输出 很快,所以我们希望尽可能少的阻塞操作。大多数时候,应用程序程序员可能会在中断级优先级线程内调用主类的read_samples方法,因为许多音频I/O子系统都是通过这种方式(例如通过回调)接收数据的。因此,我们来到第2点和第3点

  • 如果调用了read_样本,而fifo中没有足够的样本 交付所要求的数量,我们可能会拿走我们所拥有的(如果 然后立即返回,无阻塞。如果我们锁定并等待, 我们可能会影响许多其他的音频播放,中断级别 线程回调可能负责

  • 如果生产者试图写入一个完整的缓冲区,我们要等到 所有的样品都已经写好了。我们想让用户在阅读时阅读 等待写入,以便它们可以清除缓冲区中的空间,以便 我们。生产者等待是没有问题的,因此该部件不需要无锁。通过为环形缓冲区设置一个大致与我们的延迟预期相对应的大小,我们可以确保生产者给我们的 足够的数据以避免播放暂停,但仅此而已

  • 第1点和第2点对于实际实现来说是微不足道的,前提是我关于何时和何时不阻塞的设计决策似乎是合理的。第三点给我带来了一些麻烦。有没有一种有效的方法 锁定直到缓冲区不再满,并且只有当我们可以写入时才醒来 更多我可以很容易地检测出缓冲区的大小,谢天谢地,这是一个原子操作。但如何正确地锁定和解锁令我困惑,特别是因为我们确实希望能够中断锁定 例如,如果是关闭的时候,则过早关闭。我用什么做这个?条件变量?如果是这样,如果有人能提供一些伪代码,我将非常感激。我知道如何使用屏障,但还没有深入研究 条件变量太多了,我不确定我是否理解它们。尤其是自从
    他们显然可以在没有满足条件的情况下醒来,这似乎很奇怪。如果您有任何建议,我们将不胜感激。

    当生产商生产过多材料时,获得阻塞行为的正确方法是使用条件变量。生产者在达到其限制时调用wait,消费者在消耗某些数据后立即调用notify_all。然后,生产者醒来并生成更多数据,等等。

    FIFO中是否必须有实际数据?在高性能I/O中,更常见的是使指向“空”缓冲区的指针队列可供驱动程序使用。驱动程序用数据填充缓冲区(或部分缓冲区和长度),将缓冲区指针排到更高级别,并立即将另一个缓冲区指针排到下一批数据的队列中。驱动程序每次将缓冲区排队返回时都会发出信号量信号,以便更高级别的线程知道有一个信号量要出列和处理。“数据从fifo中快速推入和传出很重要”-只要只有一个生产者,设计/使用完全不需要硬锁定的队列就很简单,一个消费者,而你只是在排队等待指针。谢谢你的提示,马丁。将指针推到fifo中的缓冲区是一个好主意,我必须对此进行研究。我确实用一个条件变量解决了我原来的问题(我终于找到了正确使用它们的方法)。所以现在生产者耐心地等待消费者,就像我想的那样。