Методы избавления от блокировки низкого уровня - PullRequest
3 голосов
/ 24 сентября 2008

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

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

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

Ответы [ 3 ]

4 голосов
/ 24 сентября 2008

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

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

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

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

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

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

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

1 голос
/ 24 сентября 2008

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

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

0 голосов
/ 24 сентября 2008

Некоторые ответы здесь и здесь могут оказаться полезными при поиске способов атомарного обновления общего состояния без явных блокировок.

...