Как pthread_cond_wait (переменная conditon) разблокирует все потоки только один раз, а не несколько раз? - PullRequest
0 голосов
/ 07 февраля 2019

Я успешно реализовал поток производителя и 2 рабочих потока или потока потребителя.

Поток производителя передает условие, используя pthread_cond_broadcast.И рабочие потоки блокируются pthread_cond_wait.

Код выглядит примерно так:

Поток 1 (Поток производителя):

pthread_mutex_lock
pthread_cond_broadcast
pthread_mutex_unlock

Поток 2 (Работник / Потребитель)Поток):

work = 1
while(1)
{
  pthread_mutex_lock
  while(!work)
  {
    work = 1;
    pthread_cond_wait
  }

  // Thread operation
  work = 0;
  pthread_mutex_unlock
}

Поток 3 (рабочий / потребительский поток):

work = 1
while(1)
{
  pthread_mutex_lock
  while(!work)
  {
    work = 1;
    pthread_cond_wait
  }

  // Thread operation
  work = 0;
  pthread_mutex_unlock
}

Мой вопрос: почему поток 2 или поток 3 не выполняет себя повторно?

Другими словами, когда условие транслировалось потоком 1, допустим, что поток 2 сначала разблокирует условие, выполняет операцию потока, вызывает thread_cond_wait и блокирует себя.

Теперь поток 3 разблокирует условие,выполняет операцию с потоком, вызывает thread_cond_wait и блокирует себя.

В этот момент оба потока блокируются в ожидании условия, поэтому происходит ли сброс переменной условия?Если да, то как он знает, когда нужно выполнить сброс, поскольку вместо 2-х рабочих потоков у меня может быть 5 рабочих потоков?

Почему нить 2 и нить 3 снова не разблокируются для одного и того же состояния?

Я хотел знать внутренний механизм, о том, как потоки разблокируются для определенного условия только один раз, а не снова, пока не будет отправлено новое сообщение.

Я попытался прочитать об этом, но всеЯ мог видеть, что при отправке широковещания условия все потоки, ожидающие этого условия, разблокируются.Я не понимаю, почему один и тот же поток не разблокируется для одного и того же состояния несколько раз?

Я попытался посмотреть на pthread_cond_t, но не смог получить никакой подсказки.

Любая помощьили предложение о том, что мне не хватает или я думаю неправильно, будет оценено.

Спасибо

1 Ответ

0 голосов
/ 07 февраля 2019

Мой вопрос: почему поток 2 или поток 3 не выполняет себя заново?

Потому что не так работают переменные условия.

Inдругими словами, когда условие транслировалось потоком 1, допустим, что поток 2 сначала разблокирует условие, выполняет операцию потока, вызывает thread_cond_wait и блокирует себя.

Теперь поток 3 разблокирует условие, выполняет операцию потока ивызывает thread_cond_wait и блокирует себя.

В этот момент оба потока блокируются в ожидании условия, поэтому происходит ли сброс переменной условия?

Этот вопрос предполагает плохую модельсостояния, представленного условной переменной, для ответа как да, так и нет.Детали реализации могут варьироваться в широких пределах, но условно, основное состояние, управляемое CV, состоит из «набора ожидания» потоков, ожидающих в настоящее время CV.Эти потоки не могут продолжаться, то есть они заблокированы в резюме.

Существует три основных операции, которые можно выполнить над резюме:

  • Поток можетдобавьте себя в набор ожидания резюме, выполнив над ним операцию ожидания, что приведет к блокировке самого резюме.
  • Поток может привести к тому, что один другой поток, выбранный резюме, будет удален изнабор ожидания резюме (если оно не пустое) путем выполнения над ним операции «уведомить».В этом случае оба потока могут продолжить работу в отношении CV.
  • Поток может привести к освобождению набора ожидания CV, выполнив на нем операцию «широковещания».

CV не имеют постоянного состояния, указывающего, были ли они сигнализированы.Они просто знают свои наборы ожидания и (в реализации pthreads) мьютекс, который должны получить потоки, которые были удалены из набора ожидания, прежде чем они смогут вернуться из операции ожидания.Нет необходимости сбрасывать резюме, чтобы подготовить его к приему большего количества потоков в его набор ожидания.

Если это так, как он узнает, когда нужно выполнить сброс, поскольку вместо 2 рабочих потоков я мог бы иметь5 рабочих потоков?

Не сбрасывается, ни в каком смысле не отличается от уже описанных операций.Любой ожидающий поток добавляется в набор ожидания и не может планироваться, пока он там остается.Любые сигнальные и широковещательные операции на CV влияют на время ожидания, установленное на время выполнения операции, атомарно.Потоки, удаленные из набора ожидания, больше не блокируются в резюме, но вместо этого они могут быть заблокированы при получении соответствующего мьютекса.

Почему потоки 2 и 3 не разблокируют себя снова для одного и того жеусловие?

Потому что не так работают переменные условия.

Повторное ожидание потоков 2 и 3 - единственный вид сброса, поддерживаемый CV.Те потоки, которые были добавлены в набор ожидания, не имеют оснований думать, что они будут продолжаться до того, как (другой) сигнал или широковещательная операция будут выполнены с этим CV.Нет памяти о прошлых сигналах / трансляциях, только текущее содержимое набора ожидания.

...