Библиотеки Boost C ++: утверждение модульных тестов при взаимоблокировках - PullRequest
0 голосов
/ 25 сентября 2010

Я пишу модульный тест с Boost.Unit, и я хотел бы включить базовые тесты для взаимоблокировок в код, который я тестирую. Моей первой идеей было установить таймер крайнего срока в одном потоке при выполнении теста в другом, который, как ожидается, завершится задолго до крайнего срока. Когда таймер отключится, подтвердите, что поток не работает или не прерван. Каким образом я мог бы более точно определить взаимные блокировки?

1 Ответ

3 голосов
/ 25 сентября 2010

Один вопрос заключается в том, тестируете ли вы для фактических взаимоблокировок (т. Е. Чтобы увидеть, произошла ли взаимоблокировка) или потенциальных взаимоблокировок (т. Е. Для проверки, может ли тупик возникнуть)

Если вас интересует только обнаружение реальных взаимоблокировок, то может сработать что-то вроде того, что вы описываете.Тем не менее, я не уверен, что это будет так полезно, поскольку независимо от того, сколько раз вы выполняете тест, всегда будет вероятность того, что в будущем все еще может произойти взаимоблокировка, если синхронизация между потоками закончится простосовершенно неправильно.Это область, в которой многопоточное программирование отличается от однопоточного программирования: в многопоточной программе успешное выполнение программы один раз (или даже миллион раз) не доказывает ее правильность.

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

Если взглянуть на код недостаточно, последнее, что вы можете сделать, - это инструментПриобретение блокировок: Самый простой способ сделать это (если ваш код может работать под Linux) - это запустить ваш код в helgrind.Если вы не можете этого сделать, альтернативный метод заключается в том, чтобы обернуть ваши вызовы блокировки / разблокировки в функцию, которая регистрирует, какой поток блокировал / разблокирует какой мьютекс, а затем анализирует журнал, чтобы обнаружить несоответствия порядка блокировки "post mortem".

...