У меня есть фоновый поток для загрузки файлов. Он работает в цикле; он выполняет некоторую работу, затем спит до истечения таймаута или до тех пор, пока он не будет явно уведомлен через переменную условия, что есть больше работы. Проблема в том, что иногда мне не удается быстро выйти из потока.Как выйти из фоновой петли?
Вот упрощенная версия:
std::thread g_thread;
std::mutex g_mutex;
std::condition_variable g_cond;
bool g_stop = false;
void threadLoop()
{
while (!g_stop)
{
printf("doing some stuff\n");
std::unique_lock<std::mutex> lock(g_mutex);
g_cond.wait_for(lock, std::chrono::seconds(15));
}
}
int main(int argc, char* argv[])
{
g_stop = false;
g_thread = std::thread(threadLoop);
printf("hello\n");
g_stop = true;
g_cond.notify_one();
g_thread.join();
}
Когда я запускаю эту программу тестирования, я ожидал бы, чтобы выйти быстро, но иногда застревает в wait_for(). Я думаю, может быть, notify_one() происходит до того, как поток будет спать в wait_for(), но после проверки g_stop.
Есть ли простое решение для этого или другой шаблон проектирования, который будет работать лучше?
Вы должны изменить тип g_stop на 'atomic_bool', чтобы избежать ** неопределенного поведения **, без проблем с кешированием. Или только прочитайте его, удерживая блокировку мьютекса. –
Я не уверен в методе на C++, но в основном, когда поток находится во сне, единственный способ заставить его ответить - отправить сигнал. В C он будет использовать 'int pthread_kill (pthread_t thread, int sig)'; – AxFab
@AxFab, нет, это не полезно. Он ожидает переменную условия, поэтому вы разблокируете ее, уведомив об этой переменной условия. –