gpt4 book ai didi

c++ - QT QThread::isrunning freeze 程序在 Pi 上

转载 作者:行者123 更新时间:2023-11-28 04:56:45 25 4
gpt4 key购买 nike

我正在我的 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 check上

serial_works->isRunning()

问题出在哪里?在主机上,新表单按预期打开。

最佳答案

你在不理解这个对象在做什么的情况下试图使用 QThread。您想要做的是异步执行:做一些工作,完成后告诉我

编辑:发生了什么:

  • Client : main thread 在 worker 执行 run 之前执行 open_form
  • Rasberry Pi:worker 在主线程执行之前执行 run open_form

在圆周率上

  1. serial_works->start() 启动 worker,先执行,完成 my_function。
  2. worker 调用 this->terminate() 现在正式死亡。 terminate is a brutal way of stopping a QThread. .我什至无法推测是否调用了 wait()。
  3. 主线程执行 open_form,worker 已经不可运行。因此循环不会执行,Next_form 也永远不会显示。

错误 1:

Main_form::open_form()

正在 gui 线程中执行,而您正在休眠一个事件。这总是不正确的。您的 GUI 将在您 sleep 的时间内卡住。使用信号槽或事件。

错误 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
}

关于c++ - QT QThread::isrunning freeze 程序在 Pi 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46971765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com