Подтвердить что ты не робот

Каковы общие причины тупиков?

Тупики трудно найти и очень неудобно удалить.

Как найти источники ошибок для взаимоблокировок в моем коде? Существуют ли "шаблоны блокировки"?

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

4b9b3361

Ответ 1

Обновление. Эта недавняя статья MSDN, Инструменты и методы для определения Concurrency Вопросы, также может быть интересна


Стивен Туб в статье MSDN Монитор взаимоблокировки устанавливает следующие четыре условия, необходимые для возникновения взаимоблокировок:

  • Ограниченное количество определенного ресурса. В случае монитора на С# (то, что вы используете при использовании ключевого слова блокировки) это ограниченное число - одно, поскольку монитор является блокировкой взаимного исключения (это означает, что только один поток может одновременно иметь монитор).

  • Возможность удерживать один ресурс и запрашивать другой. В С# это похоже на блокировку на одном объекте и затем блокировку на другом, прежде чем освободить первый замок, например:


lock(a)
{
...
    lock(b)
    {
            ...
    }
}
  • Нет возможности преемственности. В С# это означает, что один поток не может заставить другой поток освободить блокировку.

  • Условие циклического ожидания. Это означает, что существует цикл потоков, каждый из которых ждет следующего, чтобы освободить ресурс, прежде чем он сможет продолжить.

Далее он объясняет, что способ избежать взаимоблокировок состоит в том, чтобы избегать (или препятствовать) четырех условий.

Джо Даффи обсуждает несколько методовдля избежания и обнаружения взаимоблокировок, в том числе известный как блокировка. При выравнивании блокировки назначаются блокировки числовые значения и потоки должны только приобретать блокировки, которые имеют более высокие числа, чем блокировки, которые у них уже есть приобрела. Это предотвращает возможность цикла. Это также часто трудно преуспеть в типичное программное приложение сегодня, и несоблюдение уровня блокировки на каждом захвате блокировки приглашает тупиковый.

Ответ 2

Классический сценарий тупиковой ситуации: A удерживает блокировку X и хочет получить блокировку Y, а B удерживает блокировку Y и хочет получить блокировку X. Поскольку ни один из них не может завершить то, что они пытаются сделать, оба будут в ожидании навсегда ( если не используются тайм-ауты).

В этом случае можно избежать взаимоблокировки, если A и B приобретают блокировки в том же порядке.

Ответ 3

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

Например:

Транзакция A

UPDATE Table A SET Foo = 'Bar'
UPDATE Table B SET Bar = 'Foo'

Транзакция B

UPDATE Table B SET Bar = 'Foo'
UPDATE Table A SET Foo = 'Bar'

Это, скорее всего, приведет к тупиковой ситуации, когда транзакция A получает блокировку в таблице A, транзакция B получает блокировку на таблице B, поэтому ни одна из них не получает блокировка для их второй команды, пока другая не закончит.

Все другие формы взаимоблокировок, как правило, вызваны использованием высокой интенсивности и блокировкой SQL Server во внутреннем пространстве, в то время как выделенные ресурсы.

Ответ 4

Никаких шаблонов взаимоблокировок (и 12 лет написания многопоточных торговых приложений). Но класс TimedLock очень помог в поиске тупиков, которые существуют в коде без массивной доработки.

http://www.randomtree.org/eric/techblog/archives/2004/10/multithreading_is_hard.html

в основном, (в dotnet/С#) вы выполняете поиск/замену всех своих операторов "lock (xxx)" с помощью TimedLock.Lock(xxx) "

Если обнаружен тупик (блокировка не может быть получена в течение указанного таймаута, по умолчанию - 10 секунд), тогда генерируется исключение. Моя локальная версия также немедленно регистрирует стек. Поднимите stacktrace (желательно отладочную сборку с номерами строк), и вы сразу увидите, какие блокировки были проведены в момент сбоя и какой из них он пытался получить.

В dotnet 1.1, в ситуации взаимоблокировки, как описано, так как удача будет иметь все блокированные потоки, это будет исключать одно и то же время. Таким образом, вы получите 2+ stacktraces и всю информацию, необходимую для устранения проблемы. (2.0+, возможно, изменил модель нарезки внутренне, чтобы не было этого повезло, я не уверен)

Ответ 5

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

Конечно, это не всегда легко организовать...

Ответ 6

Я рекомендую прочитать эту статью Herb Sutter. В нем объясняются причины проблем с блокировкой и выдвигает рамки в этой статье для решения этой проблемы.

Ответ 7

Типичным сценарием являются несоответствующие планы обновления (таблицы не всегда обновляются в том же порядке). Однако это необычно, чтобы иметь тупики, когда они находятся под большим объемом обработки.

Я склонен воспринимать тупики как факт жизни, это произойдет однажды или еще, так что у меня есть DAL, готовый обработать и повторить тупиковую операцию.

Ответ 8

Наиболее распространенный (по моим ненаучным наблюдениям) сценарий блокировки БД очень прост:

  • Два процесса читают что-то (например, запись в БД), оба приобретают общую блокировку связанного ресурса (обычно страницы БД),
  • Оба пытаются сделать обновление, пытаясь обновить свои блокировки до эксклюзивных - voila, deadlock.

Этого можно избежать, указав предложение "FOR UPDATE" (или аналогичное, в зависимости от конкретной RDBMS), если после чтения будет следовать обновление. Таким образом, процесс получает исключительную блокировку с самого начала, что делает невозможным этот сценарий.

Ответ 9

Условие, которое возникает, когда каждый из двух процессов ожидает, что он завершит befoure, предшествующий. В результате обе процедуры зависают. его наиболее comonelly многозадачность и clint/server.

Ответ 10

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

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

Ответ 11

В моем последнем проекте у меня возникла проблема с взаимоблокировками в базе данных SQL Server. Проблема в обнаружении причины заключалась в том, что мое программное обеспечение и стороннее программное обеспечение используют одну и ту же базу данных и работают в одних и тех же таблицах. Было очень трудно выяснить, что вызывает тупики. В итоге я написал sql-запрос, чтобы узнать, какие процессы вызывают блокировки SQL-выражений. Вы можете найти это выражение здесь: Тупики на SQL-сервере