私は現在、拡張された Producer-Worker モデルをシミュレートする問題に取り組んでいます。この問題では、3 人のワーカーと 3 つのツールが利用可能であり、ワーカーが作業するには 2 つのツールが必要です (および材料ですが、それらは無関係です)。ボールトに 2 つ以上のツールがある場合、ワーカーは 2 つ取得します。
これは 2 人のワーカーで問題ありません。1 人は作業してからツールを保管庫に戻し、もう 1 人の待機中のワーカーは目覚めて 2 つのツールを受け取ります。問題は、作業員が 3 人いると、常に 1 人が道具を手に入れるのに飢えていることです。
いくつかのテストの後、条件変数を待っているスレッドがスタック形式で構造化されていることに気付きました。とにかくそれをキュー形式にすることは可能ですか? (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/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));
}
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 でコードの書式設定を行うためのより良い方法はありますか? 4 つのスペース以外...