我必须在c ++中为学校项目建造比萨饼店。为了做到这一点,我必须使用线程和CondVar。我为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);
}
};
我厨房的构造函数:
Kitchen::Kitchen(int nb_cooks, float mult, int time_ing):_nb_cooks(nb_cooks), _mult(mult), _time_ing(time_ing)
{
int i = 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);
}
我建立了我的披萨:
void Kitchen::doPizza()
{
PizzaGenerator gen;
std::string order;
APizza *pizza;
std::vector<AIngredient *>pizzaIngr;
bool check;
std::cout << "I do the 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");
}
}
我的库克:
void *Cook::run()
{
while (!_stop)
{
if (_pizzaList.size() != 0)
std::cout << "I CAN COOK" << std::endl;
if (!_stop)
_cond.wait();
}
return NULL;
}
但我的康德瓦尔没有采取行动。
答案 0 :(得分:2)
此:
_mut.lock();
pthread_cond_wait(&m_cond_var, _mut.getMutex());
_mut.unlock();
从根本上误解了pthreads条件变量的工作原理。 pthread_cond_wait()
的互斥参数不仅仅是一个贪婪:条件变量必须与某个共享状态(通常称为谓词)上的条件配对,并且传递的互斥锁应该是保护共享状态的互斥锁。
换句话说,你应该使用pthread_cond_wait()
非常类似的东西:
pthread_mutex_lock(&mutex);
/* ... */
while (!condition)
pthread_cond_wait(&cond, &mutex);
/* 'condition' is now true, and mutex is held. Do some operation here that
* depends upon 'condition' being true. */
pthread_mutex_unlock(&mutex);
在这种情况下,看起来厨师等待的条件可能是&#34;至少有一个披萨等待烹饪,或停止标志已经设置&#34;。然后厨师需要按照这些方式调用代码:
pizzalist_mutex.lock();
do {
while (_pizzaList.size() == 0 && !stop)
pthread_cond_wait(&cond, pizzalist_mutex.getMutex());
if (_pizzaList.size() != 0)
{
/* remove pizza from pizza list */
pizzalist_mutex.unlock();
/* cook pizza */
pizzalist_mutex.lock();
}
} while (!stop);
pizzalist_mutex.unlock();
...其中pizzalist_mutex
是一个互斥体,用于保护pizzaList和全局stop
。
实施这个&#34;等待比萨饼列表中的披萨可能是有意义的。作为披萨列表对象本身的一种方法。