Предположим, у меня есть поток, который должен выполнять какую-то задачу периодически, но этот период равен 6 раз в час 12 раз в час (каждые 5 минут), я часто видел код, который контролирует поток петля с is_running флаг, который проверяется каждый цикл, как это:Остановка длинноволновых потоков
std::atomic<bool> is_running;
void start()
{
is_running.store(true);
std::thread { thread_function }.detach();
}
void stop()
{
is_running.store(false);
}
void thread_function()
{
using namespace std::literals;
while (is_running.load())
{
// do some task...
std::this_thread::sleep_for(5min);
}
}
Но если функция stop()
называется, скажем, 1 миллисекунду после start()
нить будет в живых 299999 дополнительных миллисекунд, пока не будит , проверяет флаг и умирает.
Правильно ли я понимаю? Как избежать сохранения (но спящего) потока, который должен был быть закончен? Мой лучший подход до сих пор является следующим:
void thread_function()
{
using namespace std::literals;
while (is_running.load())
{
// do some task...
for (unsigned int b = 0u, e = 1500u; is_running.load() && (b != e); ++b)
{
// 1500 * 200 = 300000ms = 5min
std::this_thread::sleep_for(200ms);
}
}
}
Есть ли менее грязный и более простой способ для достижения этой цели?
_6 раз каждый час (каждые 5 минут) _, хорошо 12 раз в час или каждые 10 минут? :) –
@AlexandreLavoie какой провал! Спасибо, я исправлю! :) –
http://en.cppreference.com/w/cpp/thread/condition_variable, см. Первое предложение там. Вместо того, чтобы спать в течение фиксированного времени, вы вводите условие ожидания для этого количества времени, чтобы другие потоки все равно могли прерывать вас. – stijn