【发布时间】:2015-08-25 14:22:03
【问题描述】:
我有一个用于上传文件的后台线程。它循环运行;它会做一些工作,然后休眠直到超时或通过条件变量明确通知它还有更多工作要做。问题是有时我无法让线程快速退出。
这是一个简化版:
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,不,这没有帮助。它正在等待条件变量,因此您可以通过通知该条件变量来解除阻塞。
-
@JonathanWakely 是的,你必须设置
g_stop = true。但是如果你想在等待的 15 秒之前退出,你也必须发送一个信号。 -
一个大问题是没有正确使用条件变量。您需要在持有互斥锁的同时检查谓词(例如“有工作要做”或“我应该停止吗”),然后如果谓词为假,则 wait_for() 。条件变量不会保持信号状态,因此如果有人在您不在 .wait_for() 调用中时调用 .notify() - 您会错过通知。
标签: c++ multithreading stl condition-variable stdthread