c++ - Conditional Variable doesn't wake up -
i have build pizzeria in c++ school project. in order have use thread , condvar. i'm doing condvar:
class condvar { pthread_cond_t m_cond_var; mutex _mut; public: condvar() { _mut.init(); pthread_cond_init(&m_cond_var, null); } ~condvar() { pthread_cond_destroy(&m_cond_var); } void wait() { _mut.lock(); pthread_cond_wait(&m_cond_var, _mut.getmutex()); _mut.unlock(); } void signal() { pthread_cond_signal(&m_cond_var); } void broadcast() { pthread_cond_broadcast(&m_cond_var); } };
the constructor of kitchen:
kitchen::kitchen(int nb_cooks, float mult, int time_ing):_nb_cooks(nb_cooks), _mult(mult), _time_ing(time_ing) { int = 0; _pipe = new pipeclass(); _fork = new fork(); if (_fork->isson()) { _pipe->setson(true); _run = true; _cond = new condvar(); _stock.push_back(new mushrooms(5)); cook_mutex.init(); ingr_mutex.init(); while (i < _nb_cooks) { _cooks.push_back(new cook(mult, _pizzalist, *_cond, cook_mutex)); i++; } _thread = new thread(this); run(); } else _pipe->setson(false); }
i build pizza:
void kitchen::dopizza() { pizzagenerator gen; std::string order; apizza *pizza; std::vector<aingredient *>pizzaingr; bool check; std::cout << "i pizza" << std::endl; order = _pipe->getline(); pizza = gen.createforkitchen(order); pizzaingr = pizza->getingredients(); if ((check = checkingredients(pizzaingr)) == false) _pipe->write("ko"); else if (checkcooks() + _pizzalist.size() <= (unsigned int)(2 * _nb_cooks)) { removeingredientsfromstock(pizzaingr); _pizzalist.push_back(pizza); std::cout << "je rentre dedans" << std::endl; _cond->signal(); _pipe->write("ok"); } }
and run of cook:
void *cook::run() { while (!_stop) { if (_pizzalist.size() != 0) std::cout << "i can cook" << std::endl; if (!_stop) _cond.wait(); } return null; }
but condvar doesn't act.
this:
_mut.lock(); pthread_cond_wait(&m_cond_var, _mut.getmutex()); _mut.unlock();
fundamentally misunderstands how pthreads condition variables work. mutex argument pthread_cond_wait()
isn't there embuggerance: condition variable must paired condition on shared state (often called predicate), , mutex passed should mutex protects shared state.
in other words, should use pthread_cond_wait()
this:
pthread_mutex_lock(&mutex); /* ... */ while (!condition) pthread_cond_wait(&cond, &mutex); /* 'condition' true, , mutex held. operation here * depends upon 'condition' being true. */ pthread_mutex_unlock(&mutex);
in case, looks condition cooks wait might "there @ least 1 pizza waiting cooked, or stop flag has been set". cooks need call code along these lines:
pizzalist_mutex.lock(); { while (_pizzalist.size() == 0 && !stop) pthread_cond_wait(&cond, pizzalist_mutex.getmutex()); if (_pizzalist.size() != 0) { /* remove pizza pizza list */ pizzalist_mutex.unlock(); /* cook pizza */ pizzalist_mutex.lock(); } } while (!stop); pizzalist_mutex.unlock();
...where pizzalist_mutex
mutex used protect pizzalist , global stop
.
it perhaps make sense implement "wait pizza pizza list" method of pizza list object itself.
Comments
Post a Comment