Условные переменные в pthreads и снятие нескольких блокировок

0

Извините, если это тривиальный вопрос. Но я не мог найти ответ нигде. Я пишу программу, которая использует pthreads. Один поток получает блокировку (mutex), а затем пытается вставить данные в синхронизированный буфер. Буфер имеет свой собственный мьютекс, который приобретается после вызова метода push().

Если буфер заполнен и поток должен ждать условной переменной, будет ли вызов ожидания освободить все приобретенные блокировки? Или он просто освободит тот, который связан с условной переменной (которая, оказывается, является последней приобретенной блокировкой)? Если это последний, как я могу избежать взаимоблокировок, если другой поток должен получить первый замок?

Редактировать:

Проблема у меня следующая. У меня есть два потока, скажем A и B. Thread A имеет цикл for, который вставляет данные в несколько буферов. Каждая итерация вставляет элемент в один из буферов. Поскольку это поток, он непрерывно выполняет этот цикл в другом внешнем цикле для потока. Когда B активирован, он управляет этими буферами. Но B не должен работать на буферах, если A прерывается планировщиком в середине выполнения цикла for. Поэтому я использую мьютекс, чтобы заблокировать критический раздел в A, который является циклом for.

Edit-2:

Я размышлял. И ответ на мою проблему определенно не будет заключаться в том, что условная переменная буферов также освобождает первый замок. Это означало бы, что первый замок не был даже необходим в первую очередь. Если потребительские потоки (отличные от Thread B), ответственные за удаление элементов из буферов, выполняют свою работу должным образом, Thread A возобновится в какой-то момент и цикл for будет завершен. Поэтому моя проблема должна лежать там. Я присмотрюсь и уточню.

  • 0
    Для первого вопроса, cond-wait освободит мьютекс, который вы ему дадите. Ничего больше. Т.е. пара lock + cvar для вашего sync-буфера должна освободить свою собственную блокировку для ожидания после первоначального получения. Во-вторых, если вам нужно подождать push-lock и сделать это по условию, убедитесь, что ваш входной замок сначала разблокируется (и, похоже, он может и не понадобиться, в любом случае).
  • 0
    @WhozCraig Изначально у меня вообще не было этого первого мьютекса. Но я верю, что мне это нужно. Пожалуйста, смотрите мое редактирование выше.
Показать ещё 7 комментариев
Теги:
multithreading
synchronization
pthreads

1 ответ

0
Лучший ответ

pthread_cond_wait() освободит только мьютекс, который вы передадите ему, что в вашем случае будет мьютексом буфера, приобретенным ранее в вызове push().

Похоже, у вас будет возможность тупика в вашей ситуации, но это следствие вашего высокоуровневого дизайна. Если Thread B не может быть выполнен, в то время как Thread A запускает цикл for(), но внутри цикла for() Thread A, возможно, придется дождаться, когда Thread B будет потреблять некоторые данные для прокси-сервера, тогда взаимоблокировка неизбежна.

Для этого вам нужно будет обновить свой дизайн. Одна из возможностей - добавить функцию reserve() к вашим синхронизированным буферам, которая резервирует пространство для последующего push(), но не добавляет никаких данных. Затем ваш поток A может пройти и зарезервировать необходимое пространство без сохранения внешнего мьютекса (поскольку он не добавляет никаких данных, видимых для Thread B) - если ему нужно дождаться, когда Thread B будет потреблять некоторые данные, он сделает это Вот. Один из них зарезервировал все необходимое пространство, затем он может заблокировать внешний мьютекс и нажать данные - это гарантировано, что не придется ждать Thread B, потому что пространство уже зарезервировано.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню