Стоит ли запрашивать тайм-ауты для блокировок в .NET? - PullRequest
5 голосов
/ 30 января 2009

In Release It! , Майкл Найгард объясняет, что многие катастрофические сбои системы часто бывают вызваны цепью ошибок. Например, два потока тупиковые. Теперь в пуле потоков на два потока меньше, поэтому нагрузка на другие потоки увеличивается, увеличивая их вероятность взаимоблокировок. Внезапно сервер вообще не отвечает, поскольку пул потоков исчерпан, что приводит к тому, что балансировщик нагрузки перенаправляет трафик на другие серверы (на которых выполняется один и тот же код), что увеличивает их вероятность тупики. Внезапно вся ферма не работает.

Большинство серверов RDBMS обнаруживают взаимоблокировки и определяют «проигравшего» (одна транзакция прерывается, другая может продолжаться). Напротив, в C # оператор lock будет бесконечно ждать получения блокировки.

Однако вы можете вызвать Monitor.TryEnter (lockObject, TimeSpan) , чтобы запросить блокировку или тайм-аут. Он возвращает false, если время ожидания истекло и блокировка не может быть получена. Некоторые включили это в операторы , чтобы сохранить хороший синтаксис.

Итак, мой вопрос: вы всегда получаете блокировки, используя таймауты, или нет? И какие проблемы создают таймауты по сравнению со сценарием тупика?

Ответы [ 4 ]

5 голосов
/ 30 января 2009

Я обычно использую таймауты. Самая большая проблема здесь заключается в том, что по истечении времени ожидания запрашивающая операция будет прервана. Это явно предпочтительнее блокировки. Однако здесь есть более серьезная проблема: если операция критична, и вы начинаете прерывание, потому что что-то еще заблокировано, если ваш проект не является надежным, вы можете в конечном итоге вызвать проблему сбоя фермы, которую вы описали с помощью этого метода (хотя и мягче: ваше приложение больше не будет работать, но вы не потеряете контроль).

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

1 голос
/ 30 января 2009

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

1 голос
/ 30 января 2009

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

0 голосов
/ 30 января 2009

Можно доказать, что тупиков не может быть. Также можно доказать во время выполнения, что взаимные блокировки могут возникать даже без зависимости от условий гонки (см., Например, Linux lockdep ).

Следовательно, всегда попытка блокировки не имеет смысла. Это зависит от обстоятельств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...