【发布时间】:2019-09-30 19:12:33
【问题描述】:
我正在用 C++ 编写一个生产者、多个消费者的程序。我首先调用消费者线程,然后将元素添加到数组中。 一切正常,但最终消费者线程没有加入,因为它们被卡在等待条件变量并且程序冻结。
我认为问题在于线程在循环中不断被调用,因为 currentSize 不受保护并且它们无法退出条件变量,但我不知道如何解决它。
struct Item {
public:
string name;
int time;
double height;
};
struct Monitor {
private:
Item items[12];
int currentSize;
bool finished;
mutex lock;
condition_variable cv;
public:
Monitor() {
finished = false;
currentSize = 0;
}
void put(Item item) {
unique_lock<mutex> guard(lock);
cv.wait(guard, [&] { return (currentSize < 12); });
items[currentSize] = item;
currentSize++;
cv.notify_all();
}
Item get() {
unique_lock<mutex> guard(lock);
cv.wait(guard, [&] { return (currentSize > 0); });
Item item = items[currentSize - 1];
currentSize--;
return item;
}
bool get_finished() {
return finished;
}
void set_finished() {
finished = true;
}
int get_size() {
return currentSize;
}
};
int main() {
vector<Item> items = read_file(file);
Monitor monitor;
vector<thread> threads;
vector<Item> results;
for (int i = 0; i < 4; i++) {
threads.emplace_back([&] {
while (!monitor.get_finished()) {
if (monitor.get_size() > 0) {
Item item = monitor.get();
results.push_back(item);
}
}
});
}
for (int i = 0; i < items.size(); i++) {
monitor.put(items[i]);
}
monitor.set_finished();
for_each(threads.begin(), threads.end(), mem_fn(&thread::join));
return 0;
}
【问题讨论】:
-
无关:
results.push_back(item);在多个线程中不受保护看起来并不那么安全。 -
没有
Movie、Item、read_file,很难重现。 -
至少,中断调试器并提供所有线程的当前位置。
-
@Jeffrey 您需要更新到 C++138 才能获得远程心灵感应支持。
-
read_file 只是获取数据,而 Item 是一个具有 3 个字段的结构。我认为它不相关,所以我没有包括它。电影应该是项目。
标签: c++ concurrency