C++ 音频线程
在我的应用程序中,我有一个单独的音频线程,因为这在当时听起来是个好主意,但现在我想知道其他线程将如何与音频线程通信C++ 音频线程,c++,multithreading,audio,C++,Multithreading,Audio,在我的应用程序中,我有一个单独的音频线程,因为这在当时听起来是个好主意,但现在我想知道其他线程将如何与音频线程通信 audioThread() { while(!isCloseRequested) { If(audio.dogSoundRequested) { audio.playDogSound(); } } } otherThread() { Audio.dogSoundRequested(); } 这是一种有效的音频线程方式,还是您看到了此设置的问题?
audioThread() {
while(!isCloseRequested) {
If(audio.dogSoundRequested) {
audio.playDogSound();
}
}
}
otherThread() {
Audio.dogSoundRequested();
}
这是一种有效的音频线程方式,还是您看到了此设置的问题?如果您想确保没有其他线程触及
playDogSound()
函数,请使用互斥锁锁定资源
std::mutex mtx;
audioThread() {
while(!isCloseRequested) {
if (audio.dogSoundRequested) {
mtx.lock();
audio.playDogSound();
mtx.unlock();
}
}
}
除了使用互斥外,这里还有一个用于多线程的简单设置
// g++ -o multi_threading -pthread -std=c++11 multi_threading.cpp
#include <iostream>
#include <thread>
#include <exception>
#include <mutex>
#include <climits> // min max of short int
void launch_consumer() {
std::cout << "launch_consumer" << std::endl;
} // launch_consumer
void launch_producer(std::string chosen_file) {
std::cout << "launch_producer " << chosen_file << std::endl;
} // launch_producer
// -----------
int main(int argc, char** argv) {
std::string chosen_file = "audio_file.wav";
std::thread t1(launch_producer, chosen_file);
std::this_thread::sleep_for (std::chrono::milliseconds( 100));
std::thread t2(launch_consumer);
// -------------------------
t1.join();
t2.join();
return 0;
}
//g++-o多线程-pthread-std=c++11多线程.cpp
#包括
#包括
#包括
#包括
#包括//short int的最小最大值
无效启动_消费者(){
std::cout这里的关键问题似乎是
1:如何使audio.dogSoundRequested
和isCloseRequested
线程安全
2:audioThread
正忙着等待(例如,无限旋转直到audio.dogSoundRequested
变为true
)
正如其他人所建议的,您可以使用互斥来保护这两个变量,但这是过分的——此外,在音频代码中,不使用阻塞同步是一种很好的形式,以避免出现问题
相反,假设您使用的是C++11或C++14,您可以使用一个原子变量,它是轻量级的,并且(在大多数实现中)不会阻塞:
<>而不是使代码与互斥和条件变量复杂化,考虑做一个线程安全的FIFO。在这种情况下,可以有多个写入器和一个用户。应用程序的其他线程是这个FIFO的编写者,<代码> AudioRead()/代码>是消费者。
// NOP = no operation
enum AudioTask {NOP, QUIT, PLAY_DOG, ...};
class Fifo
{
public:
bool can_push() const; // is it full?
void push(AudioTask t); // safely writes to the FIFO
AudioTask pop(); // safely reads from the FIFO, if empty NOP
};
现在,假设fifo
和audio
是应用程序类成员,那么audioThread()
就更干净了:
void audioThread()
{
bool running = true;
while(running)
{
auto task = fifo.pop();
switch(task)
{
case NOP: std::this_thread::yield(); break;
case QUIT: running = false; break;
case PLAY_DOG: audio.playDogSound(); break;
}
}
}
最后,调用代码只需将任务推入FIFO:
void request_dog_sound()
{
fifo.push(PLAY_DOG);
}
void stop_audio_thread()
{
fifo.push(QUIT);
audio_thread.join();
}
这将线程安全同步的详细信息放入Fifo类中,保持应用程序的其余部分更干净。就使用的锁而言,我知道我正在使用的openmp有自己的功能,但谢谢!您的互斥锁根本没有保护任何东西。在互斥锁中包装函数调用不会阻止另一个线程调用我不清楚到底是什么playDogSound()
在这里有。它是开始播放声音、生成音频还是渲染处理程序?这个程序应该做什么?@Marko这是一个虚拟函数,它是不是打算连续运行?例如,一次只播放一个声音?@Marko wow我已经看到了这个问题,正在考虑解决方案,如果你能提供帮助,我会的非常感谢。请给我一个布尔数组,以便我可以同时播放多个声音。例如,如果(dogSoundRequested[x]),dogSoundRequested[0]每次返回false,dogSoundRequested[10]返回true,如果你明白我说的话。
void audioThread()
{
bool running = true;
while(running)
{
auto task = fifo.pop();
switch(task)
{
case NOP: std::this_thread::yield(); break;
case QUIT: running = false; break;
case PLAY_DOG: audio.playDogSound(); break;
}
}
}
void request_dog_sound()
{
fifo.push(PLAY_DOG);
}
void stop_audio_thread()
{
fifo.push(QUIT);
audio_thread.join();
}