C++ QThread发出finished()信号,但isRunning()返回true,isFinished()返回false
下面是我的qthread实现的代码。我正试图从卫星上获取gps数据。即使程序退出C++ QThread发出finished()信号,但isRunning()返回true,isFinished()返回false,c++,qt,gps,blackberry-10,qthread,C++,Qt,Gps,Blackberry 10,Qthread,下面是我的qthread实现的代码。我正试图从卫星上获取gps数据。即使程序退出gpsSearch()slot函数,QThread也不会产生finished()信号。只要单击按钮,就会调用函数locateMe()。当线程第一次未启动并单击按钮时,它会为isRunning()函数打印真值,为isFinished()函数打印假值。我必须调用QTherad的quit()函数来手动停止线程。之后,它转到gnssProvider类中已连接的threadQuit()函数。但即使在这之后,如果我单击按钮,它也
gpsSearch()
slot函数,QThread也不会产生finished()信号。只要单击按钮,就会调用函数locateMe()
。当线程第一次未启动并单击按钮时,它会为isRunning()
函数打印真值,为isFinished()
函数打印假值。我必须调用QTherad的quit()
函数来手动停止线程。之后,它转到gnssProvider
类中已连接的threadQuit()
函数。但即使在这之后,如果我单击按钮,它也会在locateMe()
函数中为isRunning
打印真值,为isFinished()
打印假值
GPSInfo::GPSInfo()
{
hybridGPSFound = satelliteGPSFound = networkGPSFound = false;
qDebug()<<"Thread Creating";
gnssThread = new QThread;
gnssProvider = new LocationFetcher(this,GEOLOCATION_PROVIDER_GNSS,1);
gnssProvider->moveToThread(gnssThread);
connect(gnssThread, SIGNAL(started()), gnssProvider, SLOT(gpsSearch()));
connect(gnssThread, SIGNAL(finished()), gnssProvider, SLOT(threadQuit()));
}
void LocationFetcher::gpsSearch()
{
if (BPS_SUCCESS != geolocation_request_events(0))
{
fprintf(stderr, "Error requesting geolocation events: %s", strerror(errno));
return;
}
geolocation_set_provider(GPS_Search_Provider);
geolocation_set_period(GPS_Search_Period);
while (!stopThread)
{
bps_event_t *event = NULL;
bps_get_event(&event, -1);
if (event)
{
if (bps_event_get_domain(event) == geolocation_get_domain() && bps_event_get_code(event) == GEOLOCATION_INFO)
{
handle_geolocation_response(event);
break;
}
}
}
geolocation_stop_events(0);
this->quit();
}
void GPSInfo::LocateMe()
{
qDebug()<<"Thread Running: "<<gnssThread->isFinished();
qDebug()<<"Thread Running: "<<gnssThread->isRunning();
gnssThread->start();
hybridThread->start();
networkThread->start();
}
GPSInfo::GPSInfo()
{
hybridGPSFound=satelliteGPSFound=networkGPSFound=false;
qDebug()退出();
}
void GPSInfo::LocateMe()
{
qDebug()QThread生命周期的工作方式如下:
您可以调用QThread::start()
此时,isRunning()
应该开始返回true
线程内部启动。它们发出started()
信号
线程内部调用run()
除非在子类中重写它,run()
调用exec()
exec()
进入一个事件循环,并一直停留在那里,直到调用quit()
或exit()
exec()
和run()
返回内部
此时,isFinished()
应该开始返回true和isRunning()
false
内部构件发出finished()
信号
内部构件进行一些最终清理
线程真正终止
因此,您需要在完成位置获取程序后调用quit()
,但是this->quit()
没有在线程上调用quit()
!这可能就是它没有做任何事情的原因
您的代码看起来有点像是根据本文编写的:
注意她是如何给她的工人一个finished()
信号(与QThread::finished
不同)并将其连接到QThread::quit()的
slot.预期的行为是,线程在您手动终止它之前不会退出。正如塞巴斯蒂安所解释的,线程对象承载一个事件循环,因此直到事件循环退出它才会结束
简而言之,您的信号插槽连接在概念上是向后的-对象应该在完成其任务时终止线程,而不是反过来终止线程。您使用哪种Qt版本
在4.8.4之前,Qt 4.8返回了错误的值(Qt错误30251)。
此错误已在4.8.5中修复。您确定没有混淆isFinished和isRunning?您有“Thread Running:”
在这两行中。不,我没有:)我太懒了,没法解决这个问题:你能发布完整的示例吗?也许线程没有完成。我会建议尝试将代码减少到一个最小的示例,编译后仍然显示问题。这将帮助你找出问题所在,并让我们提供答案(因为线程可能很棘手,准确地查看调用函数的位置/时间非常有用)。问题到底是什么?这篇文章是正确的答案。我只想补充一点,我们需要了解更多关于threadQuit槽的信息才能说得更多。如果该槽删除了线程,听起来您可能有一个悬空的指针。非常感谢,这让我更好地理解了QThread:)一个非常全面的答案,在别处很难找到。