В этой теме много сообщений и ответов, но, похоже, ни одна из них не вполне соответствует моей проблеме.После поиска в Google и поиска в стеке, я не вижу ответа на свой вопрос.
У меня есть два потока: главный и подчиненный.Ведомое устройство должно дождаться главного устройства, прежде чем идти дальше определенной точки, поэтому я создал мьютекс в качестве глобальной переменной:
pthread_mutex_t lock;
И затем в инициализации главного потока задолго до того, как ведомое устройствоПоток может получить доступ к нему, я блокирую его:
инициализирую в главном потоке:
pthread_mutex_lock(&lock)
Затем в подчиненном устройстве, когда пришло время ждать мастера, я делаю это:
раб должен ждать здесь:
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
Между тем, снова в мастере, у меня есть это, когда пришло время "освободить" раба, который заблокирован в ожидании:
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
(Примечание: порядок блокировки / разблокировки для мастера противоположен.)
Основываясь на моем понимании мьютексов, я подумал, что раб ударит по замку, и застрял там, ожидая мастера, которыйбудет разблокировать его, а затем сразу же заблокировать его снова.С точки зрения времени, ведомому потребуется много времени (гарантировано), чтобы вернуться сюда снова, поэтому у мастера будет много времени, чтобы снова его заблокировать.Точно так же мастер не вернется сюда снова на некоторое время, и нам не нужно беспокоиться о том, что мастер или слэйв будут отбрасывать другого обратно на эти контрольные точки.
Когда он не работает должным образомЯ бросил в некоторых printf's, чтобы подтвердить, что мастер разблокирует, затем повторно блокирует мьютекс, прежде чем ведомый сможет разблокировать его.Насколько я понимаю, подчиненный запросил блокировку задолго до того, как мастер пришел туда, чтобы выполнить разблокировку и (повторную) блокировку, и независимо от того, насколько малое время между разблокировкой и (повторной) блокировкой мастера, подчиненное устройство все еще должно быть в состояниизаблокировать мьютекс, потому что он уже «в очереди» в ожидании.
Однако, я вижу, что мастер разблокирует мьютекс, а затем сразу же повторно блокирует его, даже если раб был терпеливо заблокирован в ожиданииза его шанс заблокировать его.
Вот код с принтом в нем и сгенерированным выводом:
slave:
printf("slave thread starting lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("slave thread intra lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("slave thread completed lock sequence\n");fflush(stdout);
master:
printf("master thread starting lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("master thread intra lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("master thread completed lock sequence\n");fflush(stdout);
Теперь вот что я вижу как вывод:
последовательность блокировки запуска подчиненного потока
... затем некоторое время (несколько секунд), покаподчиненное устройство блокируется, и, наконец, появляется следующее сообщение:
последовательность блокировки запуска главного потока
последовательность внутреннего блокировки главного потока
основная нить завершенапоследовательность блокировки
Между тем, дальнейший прогресс ведомого, который остается заблокированным навсегда, отсутствует.Я ожидал, что он предотвратит повторную блокировку мастера, и должен был выплюнуть свой принт, показывая, что он продвинулся вперед.Эти выходные данные ясно указывают на то, что заблокированный ведомый не получил свой шанс заблокировать мьютекс, даже если он терпеливо ждал своей очереди в очереди.
Так чего же мне не хватает в мьютексах и блокировке / разблокировке??
-gt-