[Теперь я вижу, что мой вопрос является дубликатом. Я проголосую за его закрытие.]
Можно ли надежно протестировать код без блокировок на C ++? Есть известная техника?
Можно ли составить правильный модульный тест? Возможны ли вообще правильные модульные тесты при программировании без блокировок?
Я не вижу очевидного способа заставить неправильный код без блокировки надежно выйти из строя. По-видимому, мне не хватает концепции.
(См. Также этот связанный вопрос.)
ПРИМЕР
К сожалению, параллелизму нужны длинные примеры. Я сделал пример ниже как можно короче. Насколько я знаю, пример верен, но предположим, что вы нарушили правила, изменив memory_order_release
на memory_order_relaxed
. Даже если этот пример сломан, он ложно преуспевает на моей машине. С memory_order_relaxed
пример должен потерпеть неудачу; но для целей тестирования я не знаю, как сделать неудачным.
Ты?
Модульное тестирование кажется сомнительным, когда невозможно составить тест для проверки плохого кода.
#include <atomic>
#include <thread>
#include <cstdlib>
#include <iostream>
const int threshold = 0x100;
const int large_integer = 0x1000;
// Gradually increase the integer to which q points until it reaches the
// threshold. Then, release.
void inflate(std::atomic_bool *const p_atom, int *const q)
{
while (*q < threshold) ++*q;
p_atom->store(true, std::memory_order_release);
}
int main()
{
std::atomic_bool atom{false};
int n{0};
// Dispatch the inflator, letting it begin gradually, in the background, to
// inflate the integer n.
std::thread inflator(inflate, &atom, &n);
// Waste some time....
for (int i = large_integer; i; --i) {}
// Spin until the inflator has released.
{
int no_of_tries = 0;
while (!atom.load(std::memory_order_acquire)) ++no_of_tries;
std::cout << "tried " << no_of_tries << " times" << std::endl;
}
// Verify that the integer n has reached the threshold.
if (n == threshold) {
std::cout << "succeeded" << std::endl;
}
else {
std::cout << "failed" << std::endl;
std::cerr << "error" << std::endl;
std::exit(1);
}
inflator.join();
return 0;
}