Condition_Signal() в потоках, как это работает?

#c #multithreading #thread-safety #pthreads #mutex

Вопрос:

Давайте взглянем на следующий код:

 cond_t c;
mutex_t m;
int queue_size = 0;

void enqueue(item x) {
  mutex_lock(amp;m);
  /* add x to tail */
  queue_size  ;
  cond_signal(amp;c); // Line 1
  mutex_unlock(amp;m);
}
item dequeue() {
  mutex_lock(amp;m);
  if (queue_size == 0)
     cond_wait(amp;c, amp;m); // Line 2
  /* remove from head */
  queue_size--;
  mutex_unlock(amp;m);
}
 

Из того, что я прочитал cond_wait(amp;c, amp;m); , не следует, что вы заняты ожиданием (это отправляет текущий поток в спящий режим, если m он заблокирован).

Теперь предположим, что поток t1 находится в строке 1, в то время как поток t2 находится в строке 2. t1 посылает сигнал, чтобы t2 проснулся, но так как он все еще заблокирован, то t2 вернется в спящий режим, затем t1 освободит мьютекс, но t2 все еще спит, и никто не разбудил его снова, поэтому он никогда не запустится.

Как это возможно? Сделал ли я неправильные выводы?

Комментарии:

1. «Он отправляет текущий поток в спящий режим, если m заблокирован» это неправильно, m должен быть всегда заблокирован в этот момент, и он всегда переводит поток в спящий режим и одновременно разблокирует мьютекс.

2. Вы пометили этот пост «C «. Это действительно код на C ? или это код на языке Си? Вы не должны использовать потоки Posix (pthreads) в программе на C . Вместо этого вы должны использовать std::thread , std::mutex std::condition_variable , и т. Д.

3. @Слава, если он может разблокировать мьютекс, то он может продолжать без ожидания, это не имеет смысла

4. Это действительно имеет смысл, если вы понимаете, как это работает. Вам не нужна переменная условия для ожидания освобождения мьютекса, вы просто блокируете мьютекс и будете спать, пока не сможете его получить. Переменная условия ожидает, чтобы условие изменило имя, а не мьютекс.