Supponiamo di avere una discussione che dovrebbe eseguire periodicamente qualche attività ma questo periodo è 6 volte ogni ora 12 volte ogni ora (ogni 5 minuti), ho visto spesso codice che controlla la discussione ciclo con un is_running bandiera che viene controllato ogni ciclo, in questo modo:Interruzione thread a lungo sonno
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);
}
}
Ma se la funzione stop()
viene chiamato, diciamo, 1 millisecondo dopo start()
il filo sarebbe vivo per 299999 millisecondi supplementari fino risveglia , controlla la bandiera e muore.
La mia comprensione è corretta? Come evitare di mantenere vivo (ma dormendo) un thread che avrebbe dovuto essere terminato? Il mio approccio migliore fino ad ora è la seguente:
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);
}
}
}
Esiste un modo meno sporco e più semplice per raggiungere questo obiettivo?
_6 volte ogni ora (ogni 5 minuti) _, ben 12 volte ogni ora o ogni 10 minuti? :) –
@AlexandreLavoie che fallire! Grazie, lo correggerò! :) –
http://en.cppreference.com/w/cpp/thread/condition_variable, vedere la prima frase qui. Invece di dormire per un periodo di tempo prestabilito, si entra in uno stato di attesa attendibile per la quantità di tempo così gli altri thread possono ancora interrompersi – stijn