Я в значительной степени развиваюсь в исключительно многопоточном и высокопроизводительном мире, поэтому я использую вот общую практику.
Дизайн - лучшая оптимизация - лучший алгоритм:
1) Разбейте свои функции на ЛОГИЧЕСКИ отделимые части. Это означает, что вызов делает "A" и ТОЛЬКО "A" - не A, а B, а затем C ...
2) ОТСУТСТВИЕ ПОБОЧНЫХ ЭФФЕКТОВ: отменить все открытые глобальные переменные, статические или нет. Если вы не можете полностью устранить побочные эффекты, изолируйте их в нескольких местах (сконцентрируйте их в коде).
3) Сделайте как можно больше изолированных компонентов. Это означает, что они не имеют состояния - они принимают все свои входные данные как константы и манипулируют только ЗАЯВЛЕННЫМИ, логически постоянными параметрами для получения выходных данных. Передача по значению вместо ссылки, где вы можете.
4) Если у вас есть состояние, сделайте четкое разделение между узлами без состояния и действительным конечным автоматом. В идеале конечный автомат должен быть отдельной функцией или классом, управляющим компонентами без состояний.
Отладка:
Ошибки с многопоточностью обычно бывают двух типов: взаимные блокировки и тупики. Как правило, тупики гораздо более детерминированы.
1) Видите ли вы повреждение данных ?: ДА => Возможно, гонка.
2) Возникает ли ошибка при КАЖДОМ запуске или только при некоторых запусках ?: ДА => Вероятно, тупик (гонки обычно недетерминированы).
3) Процесс когда-нибудь зависает? ДА => Где-то тупик. Если он иногда зависает, возможно, вы тоже участвуете в гонке.
Точки останова часто действуют подобно примитивам синхронизации THEMSELVES в коде, потому что они логически похожи - они заставляют выполнение останавливаться в текущем контексте, пока какой-то другой контекст (вы) не отправит сигнал на возобновление. Это означает, что вы должны рассматривать любые точки останова, которые у вас есть в коде, как изменяющие его многопоточное поведение, и точки останова будут влиять на условия гонки, но (в общем) не на взаимоблокировки.
Как правило, это означает, что вы должны удалить все контрольные точки, определить тип ошибки, а затем повторно ввести их, чтобы попытаться исправить. Иначе они просто еще больше искажают вещи.