У меня есть часть зрелого геопространственного программного обеспечения, которое недавно переписало области, чтобы лучше использовать преимущества нескольких процессоров, доступных на современных ПК. В частности, отображение, графический интерфейс, пространственный поиск и основная обработка были отброшены для разделения потоков. Программное обеспечение имеет довольно большой набор автоматизации GUI для функциональной регрессии, а еще один - для регрессии производительности. Пока все автоматические тесты проходят, я не уверен, что они обеспечивают почти достаточный охват с точки зрения поиска ошибок, связанных с условиями гонки, тупиками и другими гадостями, связанными с многопоточными потоками. Какие методы вы бы использовали, чтобы увидеть, существуют ли такие ошибки? Какие методы вы бы отстаивали, чтобы искоренить их, предполагая, что есть некоторые из них, чтобы искоренить?Подход к тестированию для многопоточного программного обеспечения
Что я делаю до сих пор, это запустить функциональную автоматизацию графического интерфейса в приложении, запущенном под отладчиком, чтобы я мог вырваться из тупиков и ломать сбои, а также планировать сборку проверок границ и повторять тесты против эта версия. Я также провел статический анализ источника через PC-Lint с надеждой найти потенциальные мертвые блокировки, но не имел каких-либо стоящих результатов.
Приложение C++, MFC, mulitple document/view, с несколькими потоками на doc. Механизм блокировки, который я использую, основан на объекте, который содержит указатель на CMutex, который заблокирован в ctor и освобожден в dtor. Я использую локальные переменные этого объекта для блокировки различных битов кода по мере необходимости, и мой мьютекс имеет тайм-аут, который вызывает мое предупреждение, если тайм-аут достигнут. Я избегаю блокировки, где это возможно, используя копии ресурсов, где это возможно.
Какие еще тесты вы бы выполнили?
Редактировать: У меня есть ответ на этот вопрос на нескольких форумах по тестированию и программированию, так как я заинтересован в том, как различные умы и школы мысли подходят к этой проблеме. Приносим извинения, если вы видите это в другом месте. Я приведу сводные ссылки на ответы в течение недели или около того
Даже с заблокированными функциями это все равно не будет безопасным для потоков. Рассмотрим: Тема 1: a-> Ref(); // работа с a-> Release(); Резьба 2: a-> Release(); Предположим, что поток 1 вызывает Ref(), когда поток 2 находится в вызове Release() между InterlockedDecrement и удалением этого ... – oefe
Переопределение параллелизма и команд, которое происходит в CPU, делает ошибки параллелизма еще более непредсказуемыми, чем пример в этой должности. См. Http://www.infoq.com/presentations/click-crash-course-modern-hardware –
@ Эско Луонтола: Правильно. Но если мой простой пример уже вызывает проблемы, то он, конечно, не станет лучше, если компилятор или процессор переупорядочат инструкции :-) – mmmmmmmm