我目前正在研究一个模拟扩展Producer-Worker模型的问题。在这个问题中,有3个工人和3个工具可供使用,并且为了工作人员他们需要2个工具(和材料,但这些工具是无关紧要的)。如果Vault中有> = 2个工具,则工作人员将采用2.否则,他们将等待条件变量,该条件变量在> = 2时将发出信号。C++ 11线程:多线程等待条件变量
这对2名工人来说很好:一个人会工作,然后将工具返回到保险库,另一个等待的工作人员将被唤醒并采取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.
...
(正如你可以看到2个从来没有得到的工具)
更新:2013年7月5日 我加入一些代码。
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
}
}
}
makeProducts:
void makeProduct(int i){
unique_lock<mutex> mainMatLock(matSearchMutex);
// make product according to i
this_thread::sleep_for(chrono::milliseconds(rand() % 1000 + 10));
}
GETTOOLS:
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;
}
感谢那些谁回答。我会尝试使用多个条件变量实现一个等待队列。
(PS有一些更好的办法做到代码格式化这里Stack Overflow上?除了四个空格...
你为什么不发布你的实际代码?你有没有尝试广播条件变量(与信号)?您尚未指定任何关于您的环境的内容,但可能需要关注http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_04_01 –
_“有没有更好的代码编写方法在堆栈溢出处进行格式化?“_输入不带空格的代码,然后突出显示整个代码块并按下Ctrl-K或按编辑框上方工具栏上的** {} **按钮 –