我正在尝试使用c ++ 11并发制作生产者 - 消费者方法。 wait
类的condition_variable
方法有一个谓词作为第二个参数,所以我想到了使用lambda函数:
struct LimitedBuffer {
int* buffer, size, front, back, count;
std::mutex lock;
std::condition_variable not_full;
std::condition_variable not_empty;
LimitedBuffer(int size) : size(size), front(0), back(0), count(0) {
buffer = new int[size];
}
~LimitedBuffer() {
delete[] buffer;
}
void add(int data) {
std::unique_lock<std::mutex> l(lock);
not_full.wait(l, [&count, &size]() {
return count != size;
});
buffer[back] = data;
back = (back+1)%size;
++count;
not_empty.notify_one();
}
int extract() {
std::unique_lock<std::mutex> l(lock);
not_empty.wait(l, [&count]() {
return count != 0;
});
int result = buffer[front];
front = (front+1)%size;
--count;
not_full.notify_one();
return result;
}
};
但是我收到了这个错误:
[Error] capture of non-variable 'LimitedBuffer::count'
我对c ++ 11和lambda函数并不是很了解,所以我发现class members can't be captured by value。但是,按价值来说,我是通过引用来捕获它们,但看起来它们是相同的。
在辉煌的显示中,我将struct成员值存储在局部变量中,并在lambda函数中使用它们,并且它有效! ......或不:
int ct = count, sz = size;
not_full.wait(l, [&ct, &sz]() {
return ct != sz;
});
显然我通过使用局部变量来破坏wait
函数的整个点,因为值被赋值一次,而有趣的部分是检查可能,应该和将要改变的成员变量。傻我。
那么,我的选择是什么?有没有什么方法可以让wait
方法使用成员变量做它必须做的事情?或者我被迫不使用lambda函数,所以我必须声明辅助函数才能完成工作?
我真的不明白为什么我不能在lambda函数中使用成员变量,但是由于Universe的主人以这种方式为c ++ 11分配了lamba函数,所以必须有一些很好的理由。
答案 0 :(得分:6)
count
是一个成员变量。无法直接捕获成员变量。相反,您可以捕获this
以实现相同的效果:
not_full.wait(l, [this] { return count != size; });