QT QThread::is在Pi上运行冻结程序
QT QThread::isrunning freeze program on Pi
我正在PI上测试一个程序。当在主机上运行它时,没有显示错误,相反,在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,因此程序在检查时被卡住
serial_works->isRunning()
问题出在哪里?在主机pc上,新表单按预期打开。
您试图使用QThread,却不了解这个对象在做什么。您想做的是异步执行:做一些工作,完成后让我知道。
编辑:正在发生什么:
- 客户端:主线程在工作线程执行run之前执行
open_form
- Rasberry Pi:工作线程在主线程执行
open_form
之前执行run
在PI 上
- serial_works->start()启动首先执行的worker,并完成my_function
- 工人呼叫
this->terminate()
,现在正式死亡。terminate是停止QThread的一种残酷方式。。我甚至无法推测是否调用了wait() - 主线程执行open_form,而辅助线程已经不可运行。因此,循环不会执行,Next_form也永远不会显示
错误1:
Main_form::open_form()
正在gui线程中执行,而您正处于事件睡眠状态。这总是不正确的。您的GUI将在您睡觉的时间内冻结。使用信号和插槽或事件。
错误2:
Serial_works很可能是Qthread的一个子类。您混淆了执行线程和管理该线程的对象您不应该将QThread子类化。
this->terminate();
this->wait();
工作线程正在执行该代码。你正在杀死自己然后等待死亡。因此,根据实现情况,您可能会永远等待、崩溃等…
您需要做的事情:使用QFuture和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
}
相关文章:
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 代码在main()中运行,但在函数中出现错误
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何在运行中期切换GTK CSS style_context
- 如何在MS Visual Studio 2019中运行QT UI
- 如何通过cpp程序运行shell脚本
- IPC使用多个管道和分支进程来运行Python程序
- 删除指向指针的指针是运行时错误吗
- QT QThread::is在Pi上运行冻结程序
- 系统会冻结如果我使用运行的守护程序重新启动或关闭,该守护程序可以使用Fanotify控制对文件的访问
- 在 QThread 中运行长时间操作并将信号发送到主线程仍会冻结 UI
- Qt -主窗口在运行时冻结
- QT GUI冻结,即使我运行在单独的线程
- 如何在 MFC 中连续运行不冻结窗口的函数?
- OpenCL(意外地)在尝试运行内核代码时冻结
- SDL冻结但继续运行