绝对多线程新手在这里。
我有一个播放音乐的多媒体应用程序。具体来说,它有一个读取一些数据的音频线程-例如波形-并将其发送到声卡。这是实时操作,因此必须以“非阻塞”方式尽快执行。
另一方面,还有另一个线程负责用户界面。用户可以在此处对该数据执行某些操作-例如通过添加或删除块来修改波形。这当然应该可行,但是音频线程必须始终保持可用数据不变地运行。
我的第一个想法是这样的(c ++-ish pthread伪代码):
音频线程:
vector<sample> samples; // this is shared between this thread and the UI thread
mutexLock();
for (Sample sample : samples)
play(sample);
mutexUnlock();
UI线程:
void onEditSample()
{
while (mutexTryLock() == 0)
{
editSamples(samples);
mutexUnlock();
break;
}
}
但是我不太确定尝试锁定部分。您认为解决此问题的最佳方法是什么?
答案 0 :(得分:1)
首先,在类似循环的UI线程中使用“尝试锁定”毫无意义。只需一个普通的锁就可以了-它要阻止的唯一线程是UI线程,而不是播放线程。
现在
这是实时操作,因此必须尽快执行 以“非阻塞”方式实现。
这不是很正确。它不必尽可能迅速执行-它需要在一定的时限内执行。 (必须在声音设备结束播放最后一组采样之前提供新的采样-必须遵守截止日期。)
因此,鉴于互斥锁将在UI线程更新样本时将音频线程锁定在外,我们所拥有的是音频线程不得被阻塞太长时间,因此UI线程必须仅将互斥锁保持在一会儿。
要最小化UI线程持有互斥量的时间,必须最小化更新样本所需的工作量。一种实现方法是使用 double-buffering -您有两个采样矢量,其中一个正由指针指示的音频线程有效地使用。当UI线程想要更新样本时,它将新样本复制到不活动的向量中(不保存互斥锁的 ),然后获取互斥锁,将指针值交换到另一个向量,然后解锁互斥体。然后,互斥锁仅保持更新单个指针值所需的时间,该时间非常短。