Вы можете использовать эту функцию:
function getNextAdIndex($aAd) {
$scores = array_map(function ($ad) { return $ad["viewed"] / $ad["rotation"]; }, $aAd);
return array_search(min($scores), $scores);
}
Возвращает индекс в $aAd
, который имеет наименьшее количество просмотров по сравнению с тем, что он в идеале должен иметь (основываясь на проценте вращения) .
$aAd[] = array('viewed' => 0, 'rotation' => 70); // 70%
$aAd[] = array('viewed' => 0, 'rotation' => 30); // 30%
// Provide the next 100 views:
for ($i = 0; $i < 100; $i++) {
$j = getNextAdIndex($aAd);
echo "showing add $j\n"; // Do whatever is needed to "display" an ad here
$aAd[$j]["viewed"]++; // Increase its number of views
}
Смотрите на Гонщика TypeMock (это в бета-версии),
править: на самом деле Alpha
http://www.typemock.com/Typemock_software_development_tools.html
Обычно возможно вызвать предсказанные условия состязания, и мертвые блокировки при помощи вещей как ManualResetEvent, чтобы получить каждый поток в ожидаемое состояние прежде, чем выпустить его - т.е. заставить поток иметь блокировку и ожидать сигнала... заставляют поток B запрашивать блокировку и т.д...
Однако - Вы могли бы обычно писать такой тест, чтобы исследовать подозреваемую ошибку, доказать, когда он фиксируется и что он не повторно появляется. Вы обычно разрабатывали бы на основе условий состязания (но тестировали бы их настолько лучше всего, как прагматично).
Можно записать класс блокировки, который обнаруживает потенциальные мертвые блокировки путем рассмотрения упорядочивания операций блокировки. Мы делаем это при наличии контекста потока, который все блокировки регистрируют в том, когда они получены (может быть сделан ОТЛАДКОЙ только опцией).
Идея состоит в том, чтобы создать график, где узлы представляют блокировки и ориентированное ребро между A, и B означает, что 'блокировка A была сохранена, когда блокировка B была получена'. Позвольте своему прогону программы с помощью нормальных нагрузок, затем проверьте на циклы в графике. Цикл означает, что существует потенциал для мертвой блокировки, даже если Ваш код не поражал его.
Я не думаю, ища условия состязания, действительно попадает в область поблочного тестирования. Более или менее по определению единственный способ протестировать на условия состязания псевдослучайным образом. Если Вы не готовы перейти к усилию по формальному доказательству правильности Вашей стратегии блокировки, необходимо будет сделать некоторое стресс-тестирование.
Все еще необходимо записать модульные тесты, для проверки к правильности алгоритмов, а не стратегии блокировки.
Когда стресс-тестирование многопоточный код, Вы захотите протестировать при условиях, где у Вас есть один ЦП на поток, где у Вас есть несколько потоков, совместно использующих ЦП, и где у Вас есть больше центральных процессоров, чем потоки (если возможный).
Не может думать о хорошем автоматизированном пути, но самое близкое, я приехал, было к записи модульного теста, который 'выставит' мертвую блокировку, был при помощи точек останова в дополнение к модульному тесту. Я просто включил некоторые инструкции, где добавить точку останова. Существует некоторое ручное включенное усилие, но с ними можно всегда выставлять худшее расписание потока случая.
Возможно, кто-то изобразил хороший способ автоматизировать этот тип функциональности? Я мог предположить автоматически выполнять отладчик, повредив один поток в определенной строке, позволив другому выполненному до особого условия, затем утверждая для модульного теста.
Я ранее использовал искусственные задержки кода, которые инициированы некоторыми параметрами в запросе. Например, один запрос говорит серверу задерживать запись между двумя записями и другим, чтобы сделать их без промежуточной задержки.
Mark Bessey пишет, это только полезно для создания репродукции, не для обнаружения проблемы.