簡體   English   中英

QT QThread ::正在Pi上運行凍結程序

[英]QT QThread::isrunning freeze program on Pi

我正在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”字樣,因此程序在檢查時卡住了

serial_works->isRunning()

問題出在哪兒? 在主機PC上,新窗體將按預期方式打開。

您試圖使用QThread而不了解該對象在做什么。 您想要做的是異步執行做一些工作,完成后告訴我

編輯:發生了什么

  • 客戶端:主線程在工作程序執行運行之前執行open_form
  • Rasberry Pi:工作者在主線程執行open_form之前執行運行

在PI上

  1. serial_works-> start()啟動工作程序,該工作程序首先執行並完成my_function。
  2. 工作人員調用this->terminate() ,現在正式死亡。 終止是停止QThread的一種殘酷方式。 我什至無法推測是否調用了wait()。
  3. 主線程執行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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM