QT QThread::isrunning 冻结程序在 Pi
Posted
技术标签:
【中文标题】QT QThread::isrunning 冻结程序在 Pi【英文标题】:QT QThread::isrunning freeze program on Pi 【发布时间】:2017-10-27 09:26:23 【问题描述】:我正在我的 PI 上测试一个程序。在主机 pc 上运行它时没有显示错误,相反,在 pi (CM3) 上运行它会冻结。
我正在尝试使用多线程。
从主线程,在构造函数中启动一个 QThread,然后当我单击按钮打开一个新表单时,GUI 冻结。在按钮槽中我需要在打开新表单之前检查构造函数中的serial_works线程是否已经启动完成,所以我添加了一个QThread::isRunning()检查;
Main_Form::Main_Form(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Main_Form)
ui->setupUi(this);
this->move(0,0);
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
connect(ui->btn,SIGNAL(clicked(bool)),this,SLOT(open_form()));
*serial_works = new SerialWorks();
serial_works->start();
void Main_form::open_form()
std::cout<<"open form slot"<<std::endl;
int i = 0;
while(serial_works->isRunning())
std::cout<<"WHILE"<<std::endl;
QThread::msleep(100);
i++;
if(i > 10)
serial_works->terminate();
Next_form *frm = new Next_form();
this.close();
frm->show();
Serial_works类中的run方法是
void Serial_works::run()
my_function();
this->terminate();
this->wait();
void Serial_works::my_function()
....stuff on serial
std::cout<<"serial works finished"<<std::endl;
我得到的输出
//serial works finished
//open_slot_form
控制台上没有打印出WHILE,因此程序卡在while检查中
serial_works->isRunning()
问题出在哪里?在主机 PC 上,新表单按预期打开。
【问题讨论】:
我无法回答您的问题,但我认为如果您列出主机架构、编译器和编译器以及在 Pi 和主机上使用的链接器标志会有所帮助? 你留下了最重要的部分,比如 "....stuff on serial" 我已经用 ./configure -no-use-gold-linker -release -opengl es2 -device linux-rasp-pi3-vc4-g++ -device-option CROSS_COMPILE=~/raspi 编译了 QT /tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -make libs -prefix /usr/local/qt5pi -extprefix ~ /raspi/qt5pi -hostprefix ~/raspi/qt5 -v 这样就可以知道架构了,my_function实现我就省略了,因为问题不存在,函数返回,串口已经关闭 Linux 版本 4.9.58-v7+ (dc4@dc4-XPS13-9333) (gcc 版本 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) 【参考方案1】:你试图使用 QThread 却不了解这个对象在做什么。您要做的是异步执行:做一些工作,完成后告诉我。
编辑:发生了什么:
客户端:主线程在worker执行run之前执行open_form
Rasberry Pi:worker 在主线程执行之前执行 run open_form
在 PI 上
-
serial_works->start() 启动worker,先执行,完成my_function。
工人致电
this->terminate()
,现已正式死亡。 terminate is a brutal way of stopping a QThread..我什至无法推测是否调用了 wait()。
主线程执行open_form,worker已经不可运行。所以循环不会被执行并且 Next_form 永远不会被显示出来。
错误 1:
Main_form::open_form()
正在 gui 线程中执行,并且您正在睡觉。这总是不正确的。您的 GUI 将在您睡觉的时间内冻结。使用信号和槽或事件。
错误 2:
Serial_works 可能是 Qthread 的子类。您将执行线程与管理该线程的对象混淆了。 你不应该继承 QThread。
this->terminate();
this->wait();
工作线程正在执行该代码。你正在杀死你自己,然后等待你的死亡。因此,根据实施情况,您可能会永远等待、崩溃等......
你需要做什么: Use QFuture and QFutureWatcher.
//inside Main_Form
QFutureWatcher<ReturnValueType> watcher;
void Main_form::open_form()
// Instantiate the objects and connect to the finished signal.
connect(&this->watcher, SIGNAL(finished()), &this, SLOT(SignalWorkFinished()));
// Start the computation.
QFuture<ReturnValueType> future = QtConcurrent::run(stuffOnSerialFunction);
this->watcher.setFuture(future);
// now handle work finish
void SignalWorkFinished()
QFuture<ReturnValueType> future = watcher.future();
//do whatever you like
【讨论】:
但是在主机 pc 上代码可以工作,我很抱歉,但为什么我要在一个事件上睡觉?在 QThread::msleep(100) 之后,我检查第二个线程是否已经完成并且在那如果代码一直持续到 frm->show(); 为什么没有打印出“WHILE”? 好吧,我明白了,但怎么可能在主机上打开表单?为什么它在 Pi 上而不是主机上冻结?以上是关于QT QThread::isrunning 冻结程序在 Pi的主要内容,如果未能解决你的问题,请参考以下文章