LINUX.ORG.RU

pthread_cond_wait/pthread_cond_signal


0

1

В упор не понимаю фразы «Следует всегда вызывать pthread_cond_signal() под защитой мьютекса, используемого с сигнальной переменной состояния. В ином случае переменная состояния может измениться между тестированием соответствующего состояния и блокировкой в вызове pthread_cond_wait(), что может вызвать бесконечное ожидание.»

Что они имеют ввиду? Что pthread_cond_wait был вызван без использования мьютекса (передали NULL ?)

★★★★

может имеется ввиду ситуация когда вызывается pthread_cond_signal а поток который должен быть заблокирован в ожидании изменения состояния кондишена не заблокирован и как раз в это время вызывает pthread_cond_wait ? так нафига посылать pthread_cond_signal не заблокированному потоку?

quest ★★★★ ()
Ответ на: комментарий от metawishmaster

говорит: интер процесс комуникейшен. по делу то есть что сказать?

quest ★★★★ ()

Насколько я понял, имеется в виду, что если при вызове pthread_cond_signal не лочить тот же самый мьютекс, который лочится перед вызовом pthread_cond_wait, то поток может зависнуть в pthread_cond_wait.

nozh ()
Ответ на: комментарий от nozh

как он может зависнуть в pthread_cond_wait если он уже залочен? выходит имеется ввиду ситуация когда поток не залочен а ему посылается сигнал

quest ★★★★ ()

Представим, что есть два треда - A и B

И представим, что они делают следующую последовательность операций:

1. A pthread_mutex_lock

2. A проверяет условие и решает, что ему надо подождать.

3. B pthread_cond_signal

4. A pthread_cond_wait

В итоге, тред A будет висеть на cond_wait, т.к. signal был раньше.

dmitry_vk ★★★ ()
Ответ на: комментарий от dmitry_vk

ну те речь о ситуации когда сигнал посылается не залоченому потоку

quest ★★★★ ()
Ответ на: комментарий от quest

Как вызывают pthread_cond_wait:

pthread_mutex_lock(mutex); // лочим мьютекс. Мютекс - это такая штука, что в каждый момент времени залочить его может не более одного потока
// ... дальше идет ваш код ...
pthread_cond_wait(cond, mutex); // Тут мютекс освобождается, а поток блокируется, пока другой поток не сделает pthread_cond_signal

В фразе, которую вы привели в своем сообщении, говорится, что pthread_cond_signal надо вызывать так:

pthread_mutex_lock(mutex); // лочим тот же самый мьютекс
pthread_cond_signal(cond);
pthread_mutex_unlock(mutex);

Что касается вызова pthread_cond_signal, когда ни один поток не заблокирован на pthread_cond_wait, то документация говорит, что такой вызов вообще никакого эффекта не возымеет.

nozh ()
Ответ на: комментарий от quest

> ну те речь о ситуации когда сигнал посылается не залоченому потоку

Сигнал посылается не нити.

tailgunner ★★★★★ ()
Ответ на: комментарий от quest

Нет, потом залочен - см пункт 1. Попробуйте на примере с кодом понять суть вышесказаного:

Thread 1:

1: pthread_mutex_lock(&m);
3: pthread_cond_wait(&c, &m);
pthread_mutex_unlock(&m);

Thread 2:

//pthread_mutex_lock(&m);
2: pthread_cond_signal(&c);
//pthread_mutex_unlock(&m);

kulti ★★ ()
Ответ на: комментарий от nozh

pthread_mutex_lock(mutex); // лочим тот же самый мьютекс
pthread_cond_signal(cond);
pthread_mutex_unlock(mutex);

спрашивается на кой его лочить если
1) pthread_cond_wait уже вызван
2) мъютекс и так будет залочен при выходе из pthread_cond_wait

quest ★★★★ ()
Ответ на: комментарий от tailgunner

>Сигнал посылается не нити.
а имею ввиду самое распространенное применение)

quest ★★★★ ()
Ответ на: комментарий от quest

> спрашивается на кой его лочить

Цитата: «В ином случае переменная состояния может измениться между тестированием соответствующего состояния и блокировкой в вызове pthread_cond_wait(), что может вызвать бесконечное ожидание.»

Честно говоря, лично я понимаю только последние 4 слова. :)

1) pthread_cond_wait уже вызван

pthread_cond_wait освобождает мьютекс и блокирует поток

2) мъютекс и так будет залочен при выходе из pthread_cond_wait

Выход из pthread_cond_wait будет только после вызова pthread_cond_signal

nozh ()
Ответ на: комментарий от quest

>> Сигнал посылается не нити.

а имею ввиду самое распространенное применение)

Я тоже. Условная переменная - это, упрощенно говоря, глобальный флаг. Ожидание сигнала состоит из собстенно ожидания и сброса флага. Для сброса и нужен мютекс. Фразы про «обязательно вызывать pthread_cond_signal под мютексом», у меня в мане нет. У меня наоборот: " The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits "

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

>у меня в мане нет
но приведенная в топике фраза гуглится на ура, вот она меня и смущает. думаю действительно речь идет об отправке сигнала без ПЕРЕД pthread_cond_wait. только зачем так делать не ясно

quest ★★★★ ()
Ответ на: комментарий от nozh

>Выход из pthread_cond_wait будет только после вызова pthread_cond_signal

это понятно)

quest ★★★★ ()
Ответ на: комментарий от quest

>>Выход из pthread_cond_wait будет только после вызова pthread_cond_signal

это понятно)

Понятно, что понятно. :) Я эту фрау привел в контексте с предыдущей. Что бы стало ясно, что пока поток ждет/потоки ждут в pthread_cond_wait, еще один поток может залочить этот мьютекс.

nozh ()
Ответ на: комментарий от quest

> но приведенная в топике фраза гуглится на ура,

«Зачем учиться в медвузе, если есть Гугл?» (с) Хаус

Это штоле? http://www.opennet.ru/docs/RUS/linux_parallel/node75.html Так там мютекс прикрывает не условную переменную, а глобальную count.

tailgunner ★★★★★ ()
Ответ на: комментарий от quest

>только зачем так делать не ясно

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

dmitry_vk ★★★ ()
Ответ на: комментарий от dmitry_vk

>Но при этом нельзя гарантировать, что сигнал будет принят другим тредом.

с чего это?
у меня есть поток - я лочу мьютекс, вызываю pthread_cond_wait и засыпаю одновременно с разлочиванием мьютекса.
в другом потоке я хочу поток разбудить - на кой черт мне трокать мьютекс? я просто вызываю pthread_cond_signal которая возвращает управление из pthread_cond_wait одновременно с залочиванием мьютекса

quest ★★★★ ()
Ответ на: комментарий от quest

> на кой черт мне трокать мьютекс?

Если у тебя нет общих ждя нитей данных - незачем. Но «condition variable is a predicate over shared data» (цитата по памяти), вот эти данные как раз и прикрываются мютексом.

tailgunner ★★★★★ ()
Ответ на: комментарий от quest

>на кой черт мне трокать мьютекс? я просто вызываю pthread_cond_signal которая возвращает управление из pthread_cond_wait одновременно с залочиванием мьютекса

Причина 1. Треды могут сшедулироваться так, что «спящий» тред еще не успел дойти до pthread_cond_wait.

Причина 2. pthread_cond_wait может проснуться просто так (это называется spurious wakeup; на линуксе, например, происходит при получении тредом сигнала). Если в это время другой тред сделать pthread_cond_signal, то этот сигнал уйдет в никуда.

Вы хотите эмулировать поведение виндовых EVENT'ов?

dmitry_vk ★★★ ()
Ответ на: комментарий от dmitry_vk

>Вы хотите эмулировать поведение виндовых EVENT'ов?

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

quest ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.