Анализ многопоточных программ [закрыто]

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

Итак, кто-нибудь знает какие-либо инструменты или методы, которые помогут анализировать и документировать все взаимодействия между потоками? FWIW, кодовая база C ++ для Linux, но мне было бы интересно услышать об инструментах для других сред.


Обновить

Я ценю ответы, полученные до сих пор, но я надеялся на что-то более изощренное или систематическое, чем совет, который по сути "добавляет сообщения журнала, выясняет, что происходит, и исправляет это". Существует множество инструментов для анализа и документирования потока управления в однопоточных программах; нет ничего доступного для многопоточных программ?


Смотрите также Отладка многопоточных приложений.

13.08.2008 15:09:51
7 ОТВЕТОВ
РЕШЕНИЕ

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

Я думаю, что есть пробная версия, которую вы можете скачать, так что, возможно, стоит попробовать. Я использовал только версию для Windows, но, глядя на веб-страницу VTune, у нее также есть версия для Linux.

6
21.08.2008 18:38:14
Я взял VTune за спин ... и обнаружил, что предпочитаю профилировщик Apple Shark, так как нахожу интерфейс и вывод интуитивно понятным и понятным. Мои 2 цента.
paxos1977 2.12.2008 00:37:50

В качестве отправной точки я хотел бы добавить сообщения журнала трассировки в стратегические точки вашего приложения. Это позволит вам проанализировать, как ваши потоки взаимодействуют, без опасности того, что процесс наблюдения за потоками изменит их поведение (как это может быть в случае пошаговой отладки). Мой опыт работы с платформой .NET и мой любимый инструмент ведения журналов - это log4net, поскольку он бесплатный, имеет широкие возможности настройки и, если вы разумно понимаете, как реализовать ведение журналов, это не окажет заметного влияния на производительность вашего приложения. Кроме того, в пространстве имен System.Diagnostics имеется встроенный класс .NET Debug (или Trace).

4
13.08.2008 15:33:28
Используйте бесплатную программу DebugView от Sysinternal в сочетании с System.Diagnostics.Debug / Trace, это отличный способ получить отладочную информацию из вашего приложения, и он намного лучше, чем окно вывода Visual Studio.
Rob 22.09.2008 02:41:11
Я просто говорю: [TestFixtureSetUp] public void ConfLog4Net () {log4net.Config.BasicConfigurator.Configure (new TraceAppender {Layout = new PatternLayout ("[% t]% m% newline"), Threshold = Level.Info}); }
Henrik 29.11.2009 22:20:39

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

1
13.08.2008 20:27:23

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

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

Посмотрите, сможете ли вы объединить несколько блокировок в одну, если это не повлияет на параллелизм. Например, если мьютексам A и B кажется, что они могут иметь взаимоблокировки, а схему упорядочивания нелегко выполнить, сначала объедините их в одну блокировку.

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

3
13.08.2008 20:41:07

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

Инструмент, который может работать для вас - это CHESS (хотя, к сожалению, он предназначен только для Windows). BLAST - еще один довольно мощный инструмент, но он очень сложен в использовании и может не поддерживать C ++. В Википедии также перечислены StEAM , о которых я раньше не слышал, но похоже, что это может сработать для вас:

StEAM - это средство проверки моделей для C ++. Он обнаруживает взаимные блокировки, ошибки сегментации, переменные вне диапазона и бесконечные циклы.

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

2
21.08.2008 19:11:07

В Java у вас есть выбор, например FindBugs (для статического анализа байт-кода), чтобы найти определенные виды несогласованной синхронизации, или множество динамических анализаторов потоков от таких компаний, как Coverity, JProbe, OptimizeIt и т. Д.

1
22.09.2008 02:19:57

Разве UML не может помочь вам здесь?

Если вы перепроектируете свою кодовую базу в UML , тогда вы сможете рисовать диаграммы классов, которые показывают отношения между вашими классами. Начиная с классов, чьи методы являются точками входа потока, вы могли видеть, какой поток использует какой класс. Исходя из моего опыта работы с Rational Rose , этого можно добиться с помощью перетаскивания; если нет связи между добавленным классом и предыдущими, то добавленный класс не используется напрямую потоком, который начал с метода, с которого вы начали диаграмму. Это должно дать вам подсказки о роли каждой темы.

Это также покажет «объекты данных», которые являются общими и объекты, которые являются специфичными для потока.

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

Это даст вам только одну часть головоломки, но это может быть полезно; Я просто надеюсь, что ваша кодовая база не слишком грязная или слишком "процедурная", в этом случае ...

1
26.09.2008 17:37:45