Вопрос

Мне интересно, и я нуждаюсь в стратегиях, которые могут быть применены для уменьшения низкоуровневой блокировки.Однако загвоздка здесь в том, что это не новый код (с десятками тысяч строк кода C ++) для серверного приложения, поэтому я не могу просто переписать все это.

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

Прямо сейчас слишком много блокировок и не так много конфликтов, так что это проблема с производительностью оборудования, вызванная паранойей.Лучший способ описать код - это представить его как однопоточный код, внезапно усеянный блокировками.

Это было полезно?

Решение

Зачем вам нужно устранять низкоуровневую блокировку?У вас есть проблемы с тупиковой ситуацией?У вас есть проблемы с производительностью?Или проблемы с масштабированием?Являются ли блокировки, как правило, оспариваемыми или неконституционными?

Какую среду вы используете?Например, ответы на C ++ будут отличаться от ответов на Java.Например.непреднамеренные блоки синхронизации в Java 6 на самом деле относительно дешевы с точки зрения производительности, поэтому простое обновление вашей JRE может помочь вам решить любую проблему, которую вы пытаетесь решить.Аналогичное повышение производительности может быть доступно в C ++ при переключении на другой компилятор или библиотеку блокировки.

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

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

Во-вторых, все неизменяемое безопасно при условии, что оно "безопасно опубликовано" (т.е.создан таким образом, что частично созданный объект никогда не будет виден другому потоку).

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top