use*_*746 8 c++ multithreading mutex condition-variable c++11
我目前正在研究一个模拟扩展的Producer-Worker模型的问题.在这个问题中,有3个工人和3个工具可供使用,而对于工人来说,他们需要2个工具(和材料,但那些是无关紧要的).如果保险库中有> = 2个工具,则工作人员将采用2.否则,他们将等待条件变量,当> = 2时将发出信号.
对于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.
...
Run Code Online (Sandbox Code Playgroud)
(你可以看到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;
}
Run Code Online (Sandbox Code Playgroud)
处理器:
//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
}
}
}
Run Code Online (Sandbox Code Playgroud)
makeProducts:
void makeProduct(int i){
unique_lock<mutex> mainMatLock(matSearchMutex);
// make product according to i
this_thread::sleep_for(chrono::milliseconds(rand() % 1000 + 10));
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
感谢那些回复的人.我将尝试使用多个条件变量在今晚实现等待队列.
(PS有没有更好的方法在Stack Overflow上进行代码格式化?除了四个空格...
Ant*_*ams 10
std::condition_variable没有指定你打电话时唤醒哪个等待线程notify_one.因此,您应该编写不关心哪个线程被唤醒的代码.标准模式是无论哪个线程被唤醒,该线程都应该完成需要完成的工作.
如果您要求以特定顺序唤醒线程,则使用其他机制.例如,您可以std::condition_variable为每个线程分别使用,然后在需要工具时将线程放入队列中.当一个线程交给工具时,它可以发信号通知对应于队列前面的线程的条件变量.然后该线程将被唤醒,其他线程将保持睡眠状态(模拟虚假唤醒).
| 归档时间: |
|
| 查看次数: |
12264 次 |
| 最近记录: |