У меня есть класс, который имеет функцию execute (). Выполнение execute ()
Функция останавливается только когда вызывается функция terminate (). Я хочу проверить функцию execute ().
class Process{
public:
void execute(){ // start execution until terminate() is called.. }
void terminate(){ //stop the processing of execute()... }
}
Мой пример модульного теста приведен ниже. Я использую MSTest.
TEST_METHOD(StartTest)
{
Process p;
bool isRunning = true;
std::thread th([&](){
p.execute();
isRunning = false;
});
th.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(300));
Assert::isTrue(isRunning);
}
Если использование потока является хорошей практикой, следует ли мне закрывать поток внутри контрольного примера, а не отсоединять его от основного потока?
Также лучшее предложение заметно.
Прежде всего доступ к isRunning
должны быть синхронизированы. В вашем примере вы можете просто использовать std::atomic<bool>
и покончим с этим.
Отказ от ответственности: прошло много времени с тех пор, как я выполнил какую-либо серию многопоточности, поэтому возьмите это с крошкой соли. Кроме того, я не проверял код, кроме проверки его компиляции.
Вот где я бы начал:
auto test()
{
std::condition_variable cv{};
std::mutex m{};
Process p{};
bool isRunning{true};
std::thread th([&] {
p.execute();
{
std::lock_guard<std::mutex> lk{m};
isRunning = false;
}
cv.notify_one();
});
{
std::unique_lock<std::mutex> lk{m};
// expect timeout
Assert::isFalse(cv.wait_for(lk, std::chrono::milliseconds(300),
[&] () { return !isRunning; }));
}
p.terminate();
{
std::unique_lock<std::mutex> lk{m};
// expect condition to change
Assert::isTrue(cv.wait_for(lk, std::chrono::milliseconds(300),
[&] () { return !isRunning; }));
}
th.join();
}
Таким образом, вы проверяете оба execute
блокировать и для terminate
прекратить и у вас есть больше гибкости. Если execute
разблокирует рано, вы не ждете своего полного тайм-аута и для terminate
у вас есть движение, чтобы дождаться завершения другого потока, и вы разблокируете его, как только он это сделает.
Если terminate () не может остановить выполнение, будет ли продолжен поток
его выполнение после окончания этого теста?
Если terminate
не останавливает исполнение тогда 2 wait_for
заканчивается после возвращения тайм-аута false
и утверждение вступает в силу. Я не знаю, какие рамки тестирования вы используете и что Assert
делает.
если он возвращает исполнение test
тогда тест будет заблокирован на join
пока нить не закончится
если он выдает исключение, то join
не называется и у деструктора th
если поток еще не закончился std::terminate
будет называться. Это можно изменить с помощью try catch
если это вызывает выход (например, звонки std::terminate
) тогда … ну … ваша программа заканчивается независимо
Это действительно проблема, которую вы должны проанализировать. Все зависит от того, что вы хотите сделать, если terminate
не может остановиться execute
в пределах вашего интервала ожидания.
если вы в порядке с ожиданием в течение test
тогда все, что вам нужно сделать, это убедиться, join
называется. Как я уже сказал, это решаемо с try catch
,
если вы хотите завершить текущий тест, но все в порядке с продолжающимся потоком, то вам нужно отсоединить поток, если terminate
не смог покончить с этим.
если вы хотите убить поток, тогда … это невозможно. Вместо этого вы можете убить все приложение через std::terminate
,
Других решений пока нет …