条件变量不会被唤醒

时间:2015-04-26 08:27:21

标签: c++ pthreads

我必须在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;
}

但我的康德瓦尔没有采取行动。

1 个答案:

答案 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;等待比萨饼列表中的披萨可能是有意义的。作为披萨列表对象本身的一种方法。