Читаем Параллельное программирование на С++ в действии полностью

Тестирование многопоточного кода на порядок сложнее, потому что точный порядок выполнения потоков не детерминирован и может изменяться от запуска к запуску. Следовательно, если в коде притаилось какое-то состояние гонки, то даже на одном и том же наборе входных данных программа иногда может работать правильно, а иногда давать ошибку. Наличие потенциальной гонки не означает, что программа будет выдавать ошибку всегда, утверждается лишь, что иногда она может сбоить.

Ввиду трудностей воспроизведения ошибки, внутренне присущих многопоточным программам, вы должны проектировать тесты очень тщательно. Желательно, чтобы каждый тест проверял как можно меньший участок кода, тогда при возникновении ошибки ее будет проще изолировать. Конкретно, проверять правильность работы операций помещения и извлечения элементов в параллельной очереди лучше напрямую, а не путем тестирования всего куска кода, в котором эта очередь используется. Очень помогает еще на этапе проектирования кода думать о том, как он будет тестироваться. См. по этому поводу раздел о тестопригодности ниже в этой главе.

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

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

• Один поток вызывает push() или pop() для проверки работоспособности очереди на самом простом уровне.

• Один поток вызывает push() для пустой очереди, а второй в это время вызывает pop().

• Несколько потоков вызывают push() для пустой очереди.

• Несколько потоков вызывают push() для заполненной очереди.

• Несколько потоков вызывают pop() для пустой очереди.

• Несколько потоков вызывают pop() для заполненной очереди.

• Несколько потоков вызывают pop() для частично заполненной очереди, в которой недостаточно элементов для удовлетворения всех потоков.

• Несколько потоков вызывают push(), а один вызывает pop() для пустой очереди.

• Несколько потоков вызывают push(), а один вызывает pop() для заполненной очереди.

• Несколько потоков вызывают push() и несколько потоков вызывают pop() для пустой очереди.

• Несколько потоков вызывают push() и несколько потоков вызывают pop() для заполненной очереди.

Проверив все эти и другие случаи, вы затем должны учесть дополнительные параметры тестовой среды.

• Что понимается под «несколькими потоками» в каждом случае (3, 4, 1024)?

• Достаточно ли в системе процессорных ядер, чтобы каждый поток работал на отдельном ядре?

• Какова архитектура процессора, на котором будет прогоняться тест?

• Как обеспечить подходящее планирование для циклов «while» в тестах?

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

<p>10.2.3. Проектирование с учетом тестопригодности</p>

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

• Обязанности всех функций и классов четко очерчены.

• Каждая функция короткая и решает ровно одну задачу.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных