Qt-Thread線程官方的推薦的寫法

2021-03-02 張小飛那些事兒

直接重寫QThread是沒有問題的,但是重寫QThread這種方式不太靈活,對於重寫的Thread來講,只有run函數才會在新的線程中。對於重寫的QThread是可以帶出來對應的數據得,但是自己響應自己的槽函數的話,就不太靈活了,Qt的老版本代碼中甚至寫了這樣的代碼。

    WorkerThread(QObject *parent = 0)
: QThread(parent)
{
moveToThread(this);
}

這種寫法是非常不清真的。包括Qt的QThread介紹中,都不推薦這樣寫了。今天給大家介紹新的實現方式,這種實現方式相當靈活,可以任意的啟動,暫停之類的操作,都是通過Qt的信號槽來實現。我們先繼續實現上一個例子。這次使用新的實現方式。

重寫QObject,move到新的線程中。

這樣是QObject自己的消息循環放到了新的線程中,跨線程之間信號槽就隨隨便便的使用了。

上代碼

class WorkThread : public QObject
{
    Q_OBJECT
public:
    WorkThread(QObject* parent = nullptr);
    ~WorkThread();
public slots:
    void start1();
    void doWork();
signals:
    void workFinished();
    void workStart();
};

//cpp
WorkThread::WorkThread(QObject* parent) : QObject (parent)
{
}
WorkThread::~WorkThread()
{
}
void WorkThread::start1()
{
    emit workStart();
    doWork();
}
void WorkThread::doWork()
{
    for (int i = 0; i < 1000; i++)
    {
        qDebug()<<i<<endl;
    }
    emit workFinished();
}

然後上邏輯代碼

    m_workerThread = new QThread();
    WorkThread* worker = new WorkThread();
    worker->moveToThread(m_workerThread);

    //開始線程
    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::ThreadStart);
    connect(m_workerThread, &QThread::started, worker, &WorkThread::start1);

    //銷毀線程
    connect(worker, &WorkThread::workFinished, worker, &WorkThread::deleteLater);
    connect(worker, &WorkThread::destroyed, m_workerThread, &QThread::quit);
    connect(m_workerThread, &QThread::finished, m_workerThread, &QThread::deleteLater);

直接看connect,一個個解釋

線程啟動,Object中的work函數開始工作,輸出1-1000

完美釋放了QThread的資源。

當然有人問你這樣的操作太複雜了,沒必要。其實對於簡單的邏輯來講,這樣確實沒必要。但是對於顆粒度控制來講,這種更有優勢,下一篇。我會針對這個代碼通過信號槽做一些控制的操作。

https://github.com/CryFeiFei/Qt_Teach/tree/master/Qt_Teach/Thread2[1]

Reference[1]

https://github.com/CryFeiFei/Qt_Teach/tree/master/Qt_Teach/Thread2: https://github.com/CryFeiFei/Qt_Teach/tree/master/Qt_Teach/Thread2

相關焦點

  • Qt線程的基本概念
    Qt中的線程Qt中的線程類是QThread。
  • Qt多線程創建
    這對於開發圖形界面程序尤其重要,當一個操作耗時很長時(比如大批量I/O或大量矩陣變換等CPU密集操作),整個系統都會等待這個操作,程序就不能響應鍵盤、滑鼠、菜單等操作,而使用多線程技術可將耗時長的操作置於一個新的線程,從而避免上述問題。使多CPU系統更加有效。當線程數不大於CPU數目時,作業系統可以調度不同的線程運行於不同的CPU上。改善程序結構。
  • C#異步和多線程以及THREAD、THREADPOOL、TASK區別和使用方法
    使用async修飾的方法返回值有三種類型void,Task,Task<T>,根據返回值類型我認為其實async/await的實現是基於Task的(個人的理解我並沒有在任何書籍或者官方資料中看到這樣的說法,歡迎交流),說完了async/await異步編程模式再來說一下在C#中三個多線程實現異步的方法的方法Thread,ThreadPool,Task。
  • java多線程|創建線程的各種方式
    }}使用匿名類來創建線程,這裡使用了lambda的寫法,也是實際開發中常用的寫法/** * @Author https://www.javastudy.cloud * @CreateTime 2019/11/01 **/public class ThreadStudy { public static
  • Python多線程—Thread和Threading
    又到周四,科普Time,今天給大家講講Python多線程中的兩個模塊,Thread和Threading。針對兩個模塊下文中會給出一些實例,給大家加深印象。 說到Python的多線程呢,先介紹一下一定繞不過去的坑,全局解釋器鎖GIL。
  • Java多線程:帶你了解神秘的線程變量 ThreadLocal
    }                System.out.println(name + ":" + threadLocal.get());            }        }    }測試結果線程1:線程1的threadLocal線程2:線程2的threadLocal
  • Qt多線程分享——線程局部存儲
    在多線程術語中,經常聽到一個詞就是「線程局部存儲」,英文Thread-local storage,簡稱TLS。我們今天就來看看這到底是一個什麼樣的神秘東西。1 在講解之前,我們先來看一個例子。: public QThread{protected: void run() { thread_name.setLocalData("MyThread1"); //...
  • C++ 線程局部變量thread_local
    __thread是GCC內置的線程局部存儲設施(Thread-Local Storage),它的實現非常高效,與pthread_key_t向比較更為快速,其存儲性能可以與全局變量相媲美,而且使用方式也更為簡單。創建線程局部變量只需簡單的在全局或者靜態變量的聲明中加入__thread說明即可。
  • UNIX(多線程):03--- 認識std::thread
    <thread> 頭文件摘要<thread> 頭文件聲明了 std::thread 線程類及 std::swap (交換兩個線程對象)輔助函數。另外命名空間 std::this_thread 也聲明在 <thread> 頭文件中。
  • 為什麼SimpleDateFormat不是線程安全的?
    It is recommended to create separate format instances for each thread.If multiple threads access a format concurrently, it must be synchronizedexternally.日期格式不同步。
  • 面經手冊 · 第19篇《Thread.start() ,它是怎麼讓線程啟動的呢?》
    JVM 線程回調五、總結六、系列推薦一、前言有句話:正因為你優秀,所以難以卓越!剛開始聽這句話還在上學,既不卓越、也不優秀,甚至可能還有點笨!  // 啟動線程  Thread::start(native_thread);JVM_END這部分代碼比較多,但核心內容主要是創建線程和啟動線程,另外 &thread_entry 也是一個方法,如下:「thread_entry,線程入口」
  • 走進C++11(二十四)一統江湖之線程 -- std::thread
    C++11的標準類std::thread對線程進行了封裝,定義了C++11標準中的一些表示線程的類、用於互斥訪問的類與方法等。應用C++11中的std::thread便於多線程程序的移值。std::thread類成員函數:(1) get_id:獲取線程ID,返回一個類型為std::thread::id的對象。
  • UNIX(多線程):14---理解線程構造函數
    t1(function_1);std::thread t2(function_2, 1);std::thread t3(function_3, 1, "hello");t1.join();t2.join();t3.join();實驗的時候還發現一個問題,如果將重載的函數作為線程的入口函數,會發生編譯錯誤!
  • ThreadPoolExecutor線程池源碼解析與應用分析
    * @param workQueue 存儲和傳遞任務的阻塞隊列10 * @param threadFactory 創建線程的工廠11 * @param handler 超過線程池最大線程容量的拒絕策略12 * @throws IllegalArgumentException 如果不滿足下列情況將拋出此異常13 * {@code corePoolSize
  • Qt Designer極速開發python桌面小工具詳解
    直接去Qt官方文檔(https://doc.qt.io/archives/qt-5.13/qtgui-module.html)查看就可以了。本節使用到的lineEdit的相關方法在這裡(https://doc.qt.io/archives/qt-5.13/qtextedit.html)五、線程執行邏輯當我們實現複雜的邏輯,處理時間較長時,此時界面就會出現「未響應」。如我實現一個對網站生成sitemap的工具,點擊按鈕運行後出現卡死,如下圖所示。
  • 官方推薦:Vue之router路由最優美寫法
    一、基礎寫法,沒有懶加載,打包分離代碼官方最基礎的路由寫法
  • Qt--QThread之三言兩語
    5、線程退出注意點做應用軟體,因為主界面的原因,業務線程可以說極其重要。如果不開線程的話,軟體很難做到流暢,一個卡頓的軟體很難被用戶買單。很多初學者會被線程的同步機制給嚇到,或者覺得加鎖會影響性能,所以乾脆會拒絕對線程的使用。但是合理和高效的使用線程,以及對多線程的掌握程度,往往又決定了軟體的性能以及面試的結果和定級。
  • Java 10 大裝 B 寫法,看完可以出去吹牛逼了!
    想不想學習裝 B 式的 Java 騷操作花式寫法?沒錯,本文棧長來教你!1、集合初始化集合的創建、賦值一步到位,想不想學?;    put("3", "cn");}};哈哈,高大上的寫法,棧長以前寫過,寫法雖然是很裝X,然而並沒有什麼卵用。
  • 從Thread開始,揭露Android線程通訊的詭計和主線程的陰謀
    通常,我們這樣了啟動一條線程。Thread threadDemo = new Thread(() -> {    });threadDemo.start();那麼start()背後究竟隱藏著什麼樣不可告人的秘密呢?是人性的扭曲?還是道德的淪喪?讓我們一起點進start()。探尋start()背後的秘密。
  • Qt 開發經驗總結
    ,真正的耗時是在運算以及運算後的處理,而不是收發數據,在一些小數據量運算處理的項目中,一般不建議動用線程去處理,線程需要調度開銷的,不要什麼東西都往線程裡邊扔,線程不是萬能的。資料庫處理一般建議在主線程,如果非要在其他線程,務必記得打開資料庫也要在那個線程,即在那個線程使用資料庫就在那個線程打開,不能打開資料庫在主線程,執行sql在子線程,很可能出問題。