2010-07-29 2 views
1

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

ответ

0

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

+0

К сожалению, это для теста, где я не могу получить один из мьютексов. Думаю, я просто буду продолжать издеваться над другими вещами, пока не опустится до одного мьютекса. –

1

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

0

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

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

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

0

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

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

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

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

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