【发布时间】:2011-01-04 11:05:09
【问题描述】:
我有一个围绕 std::deque 的包装器,我用它来排队音频数据(通过 libavcodec 进入块,如果这很重要的话)。
这个函数接受一个 16 位数据的缓冲区并将其添加到双端队列
void AVAudioBuffer::enqueue(int16_t* src, size_t num, double pts) {
// Save current size of buffer
size_t size = data_buffer_.size();
lock();
data_buffer_.insert(data_buffer_.end(), src, src+num);
unlock();
// Push PTS value onto queue
if (pts != AV_NOPTS_VALUE) {
pts_values_.push_back(pair<int,double>(size, pts));
}
}
锁定/解锁的定义:
void lock() { SDL_mutexP(mute_access_); }
void unlock() { SDL_mutexV(mute_access_); }
我的问题是,当 data_buffer_.insert 语句包含在代码中时,这个函数所在的线程会执行一次然后锁定。如果我删除代码,它可以工作。我尝试用 src 数据的手动迭代替换插入,为每个元素调用 push_back(),这也导致线程锁定。
这是将数据附加到双端队列的有效方法吗?我在一个测试程序中尝试过,它似乎工作正常,文档似乎暗示它没问题。为什么这会导致我的线程死掉?
更新信息:添加了锁定/解锁失败时的错误消息,它们都成功了。我对它们进行了检测以验证它们是成对执行的,而且确实如此。一定是 deque::insert 调用搞砸了,我可以删除它,然后事情又开始了。
更新:我发现了问题,我重构了代码并错过了一个常量,所以出队总是检查为满,导致循环 =(
【问题讨论】:
-
“导致线程锁定”是什么意思?如果你在调试器中查看它,它在哪里“锁定”(调用堆栈)?
-
抱歉,lock()/unlock() 函数是 SDL 互斥体的包装器,我会用它们的定义更新帖子。
-
您能否发布或多或少完整的代码,包括双端队列部分和锁定/解锁功能。您没有在发布的代码中使用 size 和 pts 变量,因此您可能没有显示可能导致发现的重要内容:)
-
对,我有第二个双端队列,我已经将其视为问题的根源,所以我删除了它,我会更新代码。
-
你有没有试过在解锁过程中检查
SDL_mutexV()的返回值,以确保它返回0(即“成功”)?