Oboe C++ 线程——如何在不阻塞的情况下读取和写入队列
Oboe C++ Threads - How to read and write to a queue without blocking
我正在尝试使用双簧管为音频系统编写缓冲区,注意事项是
Callback do's and don'ts You should never perform an operation which
could block inside onAudioReady
. Examples of blocking operations
include:
allocate memory using, for example, malloc()
or new;
file operations such as opening, closing, reading or writing;
network operations such as streaming;
use mutexes or other synchronization primitives sleep
stop or close the stream
Call read()
or write()
on the stream which invoked it
音频线程从我的缓冲区中读取,解码器线程写入它,正如您可以想象的那样,在出现线程问题之前一切都很好。我的主要问题是我只能使用互斥锁来解决这个问题,但如果我这样做的话我将阻塞其中一个线程,如果音频线程被阻塞,则基本上不会播放声音,从而导致“爆米花”声。 (一个听着很烦人的声音)
我通过向其提供数据的回调来播放声音。
DataCallbackResult
OboeStreamCallback::onAudioReady(AudioStream *audioStream, void *audioData, int32_t numFrames) {
// fill data here
return DataCallbackResult::Continue;
}
所以我的主要问题是如何解决从音频线程读取数据又不阻塞音频线程以便它仍然可以播放音频的问题?
这听起来不可能。没有互斥锁,如何保证线程安全?双簧管如何期望您不使用互斥体进行动态音频解码?
您可以为 reading/writing 数据使用线程安全的无锁队列。这将避免对互斥锁的需要,速度会快得多,并且应该可以解决您的“爆米花”问题。
可以在此处找到示例实现:https://github.com/google/oboe/blob/master/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h
我正在尝试使用双簧管为音频系统编写缓冲区,注意事项是
Callback do's and don'ts You should never perform an operation which could block inside
onAudioReady
. Examples of blocking operations include:allocate memory using, for example,
malloc()
or new;file operations such as opening, closing, reading or writing;
network operations such as streaming;
use mutexes or other synchronization primitives sleep
stop or close the stream
Call
read()
orwrite()
on the stream which invoked it
音频线程从我的缓冲区中读取,解码器线程写入它,正如您可以想象的那样,在出现线程问题之前一切都很好。我的主要问题是我只能使用互斥锁来解决这个问题,但如果我这样做的话我将阻塞其中一个线程,如果音频线程被阻塞,则基本上不会播放声音,从而导致“爆米花”声。 (一个听着很烦人的声音)
我通过向其提供数据的回调来播放声音。
DataCallbackResult
OboeStreamCallback::onAudioReady(AudioStream *audioStream, void *audioData, int32_t numFrames) {
// fill data here
return DataCallbackResult::Continue;
}
所以我的主要问题是如何解决从音频线程读取数据又不阻塞音频线程以便它仍然可以播放音频的问题?
这听起来不可能。没有互斥锁,如何保证线程安全?双簧管如何期望您不使用互斥体进行动态音频解码?
您可以为 reading/writing 数据使用线程安全的无锁队列。这将避免对互斥锁的需要,速度会快得多,并且应该可以解决您的“爆米花”问题。
可以在此处找到示例实现:https://github.com/google/oboe/blob/master/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h