【问题标题】:Adding block of elements to the end of std::deque将元素块添加到 std::deque 的末尾
【发布时间】: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(即“成功”)?

标签: c++ deque


【解决方案1】:

这种插​​入双端队列的方法是完全有效的。

锁定的来源很可能是锁定本身。所有对 data_buffer_ 的访问都应该同步(读取和写入),包括对 data_buffer_.size() 的调用。如果一个线程从 data_buffer_ 读取数据,而另一个线程向它写入数据,您可能会得到随机的、未定义的行为。

如果在修复该问题后仍处于锁定状态,请查找不匹配的 lock()/unlock() 对或死锁。我还假设您使用的是原子锁。

查看更新后的代码,您还应该同步对 pts_values_ 的访问。

【讨论】:

  • 这就是我很好奇的地方,猜猜如果不是一个糟糕的电话,我只需要深入了解它的锁定位置。
【解决方案2】:

由于 STL 的使用很好,如图所示,我建议仔细查看同步。 SDL 互斥函数在出错时返回 -1。例如,检查 lock()unlock() 并引发异常。您也可以在这些函数的条目上记录线程 ID。

我还会检查输入值是否正确 - 使 num 不会溢出输入缓冲区。

优秀 C++ 技术的插件 - 养成使用 RAII 进行锁管理的习惯。这就是 C++ 析构函数的发明目的:)

【讨论】:

  • 如果任一状态为 -1,则添加错误消息,并且看起来锁定和解锁都工作正常。
【解决方案3】:

听起来你需要一些线程锁定。如果另一个线程正在从队列中读取(并因此更新),那么你必须锁定它

哎呀——那里有一把锁。我的猜测是锁不起作用或阅读器没有锁定

阅读器线程是否也锁定?你确定这把锁实际上是锁着的吗?

【讨论】:

    猜你喜欢
    • 2013-02-14
    • 1970-01-01
    • 2013-07-15
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多