Obecnie pracuję nad problemem symulującym rozszerzony model Producent-Pracownik. W tym problemie są dostępne 3 pracowników i 3 narzędzia, a dla pracowników do pracy potrzebne są 2 narzędzia (i materiały, ale te są nieistotne). Jeśli w skarbcu są> = 2 narzędzia, robotnik wybierze 2. Inaczej będą czekać na zmienną warunku, która będzie sygnalizowana, gdy> = 2.C++ 11 Wątek: wiele wątków oczekujących na zmienną warunku
Jest to w porządku z 2 pracownikami: jeden będzie pracował, a następnie zwróci narzędzia do skarbca, a drugi pracownik oczekujący zostanie przebudzony i zabierze 2 narzędzia. Problem polega na tym, że przy 3 pracownikach zawsze będzie ktoś głodny, aby zdobyć narzędzia.
Po kilku testach zauważyłem, że wątki oczekujące na zmienną warunku mają strukturę stosu. Czy mimo to istnieje możliwość umieszczenia go w kolejce? (1 czeka, 2 czeka i czeka 3), gdy 1 się obudzi i chce wykonać drugą, musi poczekać za 2 i 3.)
Oto jedno przykładowe wyjście. Kod jest za długi, więc opublikuję go, jeśli jest to naprawdę konieczne. Istnieją 3 wątki robocze i 1 mutex narzędzia. Kto głoduje, różni się co drugi bieg.
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.
...
(Jak widać 2 nigdy nie dostaje narzędzia ...)
aktualizacja: 2013/07/05 dodałem trochę kodu.
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;
}
Procesor:
//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;
}
Dzięki ci, którzy odpowiedzieli. Spróbuję zaimplementować dzisiejszą kolejkę oczekiwania przy użyciu wielu zmiennych warunkowych.
(PS Czy jest jakiś lepszy sposób to zrobić formatowanie kodu tutaj na przepełnienie stosu? Inny niż czterech miejscach ...
Dlaczego nie zamieścisz swojego prawdziwego kodu? Czy próbowałeś nadawania na warstwie zmiennej (przeciw sygnałowi)? Nie określiłeś niczego w swoim środowisku, ale możesz rzucić okiem na http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_08_04_01 –
_ "Czy jest jakiś lepszy sposób na zrobienie kodu formatowanie tutaj w Stack Overflow? "_ Wprowadź kod bez spacji, a następnie podświetl cały blok kodu i naciśnij Ctrl-K lub naciśnij przycisk ** {} ** na pasku narzędzi nad polem edycji –