Два мьютекса Кондвар - PullRequest
1 голос
/ 29 июля 2010

Если у меня заблокированы 2 мьютекса, и у меня есть condvar для каждого, есть ли простой способ подождать, пока или condvar сработает?Я хочу оставить удержание обоих замков снова, и с (по крайней мере) одним из condvars было сигнализировано.

Ответы [ 4 ]

1 голос
/ 29 июля 2010

не простой способ, который я вижу, я бы просто создал третий condvar и mutex, потому что вы действительно ждете другого условия.

0 голосов
/ 29 августа 2011

Просто напишите функции синхронизации, которые делают именно то, что вы хотите. Ничего встроенного в этом нет, но написать очень просто.

Один из подходов - иметь главную таблицу ожидания, защищенную собственным мьютексом. Для ожидания вы выделяете новую переменную условия и новый объект ожидания. Вы заполняете объект ожидания тем, что ожидаете, и новой переменной условия. Вы получаете мьютекс главной таблицы ожидания, добавляете свой объект в главную таблицу ожидания и блокируете собственную переменную условия. Чтобы сигнализировать, вы изменяете любые предикаты, приобретаете мьютекс в главной таблице ожидания, смотрите, для каких потоков выполняются их условия, и сигнализируете каждую из своих выделенных переменных условия.

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

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

Как правило, лучшее изменение дизайна - это не заставлять потоки ждать такого рода вещей. Вместо этого, когда работа должна быть выполнена, попросите поток, который обнаружил условие, которое означает, что работа должна быть выполнена, добавить рабочий элемент в очередь. Затем рабочие потоки могут ожидать размещения заданий в этой очереди. Если есть два различных условия, которые необходимо обработать, есть два задания, которые могут быть выполнены любым потоком.

0 голосов
/ 29 июля 2010

Редизайн?Не зная о том, что вы хотите сделать: попробуйте использовать один мьютекс и несколько condvars.Если вы хотите подождать, пока один из condvar запустит третий condvar, который запускается каждый раз, когда запускается первый или второй (или что-то в этом роде).

0 голосов
/ 29 июля 2010

Нет. Вы в конечном итоге с расой. Представьте, что оба сигнала отправляются до возврата pthread_cond_wait. Один выбрасывается, и они неразличимы.

Другой способ думать, как говорит Люк, - это то, что происходят два разных условия. Когда вы получаете сигнал, вы дважды проверьте состояние. Если есть два условия, ясно, что есть условие гонки, если другое условие может измениться, пока вы проверяете его.

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

...