我的代码中有一个有界缓冲区,用于在生产者线程和消费者线程之间移动数据。 这就是缓冲区的样子
template <class T>
class BoundedBuffer {
private:
std::queue<T> buffer;
int capacity;
std::size_t bufferSize; // helps when despositing thread deposits at a lower rate than the fetching thread fetches
std::mutex lock;
std::condition_variable not_full;
std::condition_variable not_empty;
public:
BoundedBuffer(int capacity) : capacity(capacity), bufferSize(0) {}
void deposit(T data)
{
std::unique_lock<std::mutex> l(lock);
// Wait if buffer full
bool bWait = not_full.wait_for(l, std::chrono::seconds(3), [this] {return buffer.size() != capacity; });
if (bWait)
{
buffer.push(data);
not_empty.notify_one();
}
}
T fetch()
{
std::unique_lock<std::mutex> l(lock);
// Wait if buffer empty
not_empty.wait(l, [this]() {return ((buffer.size() != 0) && (buffer.size() > bufferSize)); });
T result = buffer.back();
buffer.pop();
bufferSize = buffer.size();
not_full.notify_one();
return result;
}
};
生产者线程deposit
和消费者线程fetch
es。这对我来说已经按预期工作了,但最近有时候会出现以下错误:
Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\deque
Line: 505
Expression: deque iterators incompatible
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
Project.exe has triggered a breakpoint.
我认为断点是在buffer.pop();
行上触发的,因为在项目中断后,下一行会突出显示以运行。
程序中断后我检查了缓冲区的内容,缓冲区不为空。我看到调试器无法读取缓冲区的第0个元素的第0个元素,这可能意味着它已损坏但我不明白为什么因为我在代码运行后才遇到此错误几分钟,缓冲区已经多次使用了。在我的情况下,缓冲区的T
ype是std::vector<ImagePtr>
,其中ImagePtr
是来自闭源SDK的用户定义类型。
导致此错误的原因是什么?如何解决?
更新:我不太确定,但问题可能是每次ImagePtr
后deposit
图像在生成器线程中被释放。我想如果图像在它pop
之前被释放,那就是触发错误的原因。由于我已经停止发布图片,我还没有再遇到这个错误。