Есть проблема с этим использованием кода условия повышения

StackOverflow https://stackoverflow.com/questions/1033981

Вопрос

Будет ли этот код ждать мьютекс внутри void push (data) производителя?

Если так, то как мне обойти это?

boost::mutex access;
boost::condition cond;

// consumer
data read()
{
  boost::mutex::scoped_lock lock(access);

  // this blocks until the data is ready
  cond.wait(lock);

  // queue is ready
  return data_from_queue();
}

// producer
void push(data)
{
  //<--- will a block ever happen here?
  boost::mutex::scoped_lock lock(access);
  // add data to queue

  cond.notify_one();  
}

Допустим, у меня есть пул потоков для цикла (;;), и я прочитал read () из потока в этом пуле. Затем я обрабатываю данные на нем. И я вызываю push () с каким-то внешним потоком. У меня вопрос: может ли этот внешний поток когда-либо блокировать вызов push (data)?

Это было полезно?

Решение

Когда вызывается .wait (), он блокирует вызывающий поток в вашем пуле потоков и освобождает мьютекс. Он вернется, когда кто-то вызовет notify_one () или notify_all (). Перед тем как поток, который был заблокирован, вернется, он повторно получит мьютекс и разблокирует поток в вашем пуле потоков.

Таким образом, вызов void push (data) вашим внешним потоком будет временно блокироваться до тех пор, пока не будет вызван .wait ().

См. расширенную документацию по функции ожидания условия. .

Другие советы

wait может вернуться без вызова notify . Это называется ложным пробуждением . Чтобы справиться с этим, код, использующий условие, всегда должен иметь цикл вокруг wait , который проверяет, действительно ли ожидаемое условие действительно действует. Например:

queue data_queue;
boost::mutex access;
boost::condition cond;

// consumer
data read()
{
  boost::mutex::scoped_lock lock(access);

  while (queue.is_empty()) {
    // this blocks until the data is ready
    cond.wait(lock);
  }

  // queue is ready
  return data_from_queue();
}

// producer
void push(data)
{
  boost::mutex::scoped_lock lock(access);

  // add data to queue
  queue.push_back(data);

  cond.notify_one();  
}

Концептуально, «условие» это своего рода заблуждение. Вместо этого вы можете думать об этом как о сигнале. Вы даете сигнал другому потоку или потокам проснуться, но ничего не обещаете. Просто "Эй, может быть, есть некоторые данные готовы, почему бы вам не проверить, а?"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top