我目前正在解决一个模拟扩展的生产者-消费者模型的问题。在这个问题中,有3个工人和3个可用的工具。为了让工人工作,他们需要2个工具(材料不相关)。如果保险库里有2个或以上的工具,工人将取走2个。否则,他们将等待条件变量被信号通知,当保险库里有2个或以上的工具时再行动。
对于有2个工人的情况,情况还好:一个工人会工作然后把工具还回保险库,另一个等待的工人会醒来并取走两个工具。但是问题在于,对于有3个工人的情况,总会有一个工人因得不到工具而挨饿。
经过一些测试,我注意到等待条件变量的线程是以堆栈形式结构化的。是否有任何可能使之成为队列形式呢?(1等待,2等待,3等待。当1被唤醒并想要做另一个时,他必须排在2和3的后面等待。)
这是一个示例输出。代码太长了,所以如果真有必要,我会发布它。有3个工人线程和1个工具互斥体。每次运行都会有不同的工人挨饿。
对于有2个工人的情况,情况还好:一个工人会工作然后把工具还回保险库,另一个等待的工人会醒来并取走两个工具。但是问题在于,对于有3个工人的情况,总会有一个工人因得不到工具而挨饿。
经过一些测试,我注意到等待条件变量的线程是以堆栈形式结构化的。是否有任何可能使之成为队列形式呢?(1等待,2等待,3等待。当1被唤醒并想要做另一个时,他必须排在2和3的后面等待。)
这是一个示例输出。代码太长了,所以如果真有必要,我会发布它。有3个工人线程和1个工具互斥体。每次运行都会有不同的工人挨饿。
1 Tools taken. Remaining: 1
2 Waiting on tools...
3 Waiting on tools...
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
...
< p>(正如您所看到的,2永远不会得到工具...)
更新:2013/07/05 我添加了一些代码。
int tools = 3; //global
string last; //current last product on output buffer
mutex toolsMutex;
mutex matSearchMutex;
int main() {
//Initializing Producers
Producer prod1(1);
Producer prod2(2);
Producer prod3(3);
thread p1(processor,1);
thread p2(processor,2);
thread p3(processor,3);
p1.detach();
p2.detach();
p3.detach();
while(true) {//forever running
}
return 0;
}
处理器:
//Processor method
void processor(int i) {
srand(time(NULL));
while (true) { //forever running
bool hasTools = false;
bool productMade = false;
while (productMade == false) { //while product has yet to be made.
//choose what to make...
if (hasTools == false) {
thread matT(getMaterials,whatToMake);
thread toolT(getTools,i);
toolT.join();
matT.join();
hasTools = true;
}
else { //tools acquired but no materials
thread matT(getMaterials,whatToMake);
matT.join();
}
if (recordedLast.compare(last) != 0) {
//return materials and acquire new ones the next run
continue;
}
else {
makeProduct(whatToMake);
unique_lock<mutex> locker(toolMutex);
tools = tools + 2;
cout << i << " Operator Product made. Tools returned. Tools now:" << tools << endl;
productMade = true;
if (tools >=2)
toolsCV.notify_one();
}
//done processing
}
}
}
制作产品:
void makeProduct(int i) {
unique_lock<mutex> mainMatLock(matSearchMutex);
// make product according to i
this_thread::sleep_for(chrono::milliseconds(rand() % 1000 + 10));
}
获取工具:
void getTools(int i) {
unique_lock<mutex> locker(toolMutex);
if (tools <2) {
cout << i << " Waiting on tools..." << endl;
toolsCV.wait(locker);
}
tools = tools - 2;//tools acquired
cout << i <<" Tools taken. Remaining: " << tools << endl;
}
感谢回复。今晚我会尝试使用多个条件变量实现等待队列。
(附注:在Stack Overflow上有更好的代码格式化方法吗?除了用四个空格...)