【发布时间】:2010-08-11 23:34:14
【问题描述】:
好的,你明白我会解释这个问题: 我正在使用一个名为 ClanLIB 的库(不是我的选择),该库 SEEMLY(我不确定,甚至阅读源代码)创建了一个处理声音的线程。
这个线程,当缓冲区为空时,会尝试获取更多数据,这通常会在数据生成库太慢而无法在声卡到达缓冲区结束之前提供更多数据时导致欠载。
所以我添加了自己的线程,它不断在背景上产生声音。
这很好用,只是我自己的线程有时会占用过多的 CPU 时间并冻结其他所有内容。为了解决这个问题,我添加了条件等待。
条件等待发生在缓冲区已满时,当 ClanLIB 请求更多数据时,会发出等待信号,因此缓冲区写入线程会继续(直到再次满)。
我的问题是,由于我添加了这个条件等待、ClanLIB 声音线程和我自己的音乐线程,有时会“失控”,在应用程序的其余部分冻结时播放音乐。
什么样的奇怪情况会导致这种情况?
伪代码:
//main thread (that get frozen)
start_sound_thread();
do_lots_of_stuff();
quit();
//Sound Thread:
While(true)
{
play(buffer);
if(buffer_empty)
{
mutex.lock()
buffer = buffer2;
if(buffer2_full)
{
signal(cond1);
buffer2_full = false;
}
mutex.unlock()
}
}
//Music Library Thread:
while(true)
{
mutex.lock()
if( check_free_space(buffer2) == 0)
{
buffer2_full = true;
condition_wait(cond1);
}
write_music(buffer2);
mutex.unlock()
}
【问题讨论】:
-
我正在使用 pthreads,但我也在其他地方使用 Lua,而 Lua 使用 boost 线程(我不知道 boost 线程是如何工作的)
-
会将 condition_wait(cond1) 放入循环帮助中,boost.org/doc/libs/1_41_0/doc/html/thread/…?
-
我不这么认为... condition_wait 的工作原理是释放互斥锁,并等待“信号”警告它可以继续(然后它就像一个“lock_mutex()”并等待用于释放互斥锁)
-
关于循环,我想到了这一点:en.wikipedia.org/wiki/Spurious_wakeup
-
确实,虚假唤醒是可能的!现在我修复了代码,因此它们不会发生(即:再次检查缓冲区已满情况的循环)但问题仍然存在:(
标签: c++ multithreading pthreads buffering