Qt 的多線程

Qt 中的多線程主要用于處理耗時操作,避免阻塞主線程(UI 線程),從而提高程序的響應性和運行效率。以下是 Qt 多線程的相關技術總結:

常見的多線程實現方式

  • 繼承 QThread 類 :最基礎的實現方式,具體步驟為繼承 QThread 類,重寫其 run() 函數,在 run() 函數中編寫線程要執行的代碼,然后調用 start() 函數啟動線程。例如:

    • 定義一個自定義線程類 CameraThread,繼承自 QThread,在 run() 函數中進行相機數據采集等耗時操作,并通過信號將采集到的數據傳遞給主線程。

    • 在主線程中創建該線程對象,連接線程的信號與主線程的槽函數,啟動線程后,子線程中的 run() 函數開始執行,主線程則繼續運行,不會被耗時操作阻塞。

  • Worker + moveToThread 模式 :推薦使用的方式,更加靈活。其實現步驟為先創建一個工作類(QObject),定義該類的具體工作內容;再創建一個 QThread 對象;然后通過 moveToThread() 方法將工作對象移動到子線程;接著連接子線程的啟動信號與工作對象的任務槽函數,以及工作對象的任務完成信號與主線程的槽函數,最后啟動子線程。

    • 例如,定義一個 CameraWorker 類,在其中定義數據采集任務的槽函數 doWork(),以及任務完成后的信號 frameReady。在主線程中創建 QThread 對象和 CameraWorker 對象,將 CameraWorker 對象移動到子線程,連接相關信號與槽函數,啟動子線程后,CameraWorker 對象的 doWork() 函數在子線程中執行,采集到的數據通過信號傳遞給主線程進行 UI 更新。

  • 使用 QThreadPool 線程池 :適用于需要管理多個線程的場景,可避免頻繁創建和銷毀線程帶來的開銷。需創建一個繼承自 QRunnable 的任務類,并重寫其 run() 函數,在該函數中定義任務的具體執行邏輯,然后將任務對象提交到全局線程池中執行。

    • 比如,定義一個 MyTask 類繼承自 QRunnable,在 run() 函數中實現相應的任務代碼,接著在主線程中創建 MyTask 對象,并通過 QThreadPool::globalInstance()->start(task) 將任務提交到線程池,線程池會自動分配線程來執行任務。

  • 利用 QtConcurrent 框架 :提供了更高級的多線程編程方式,無需顯式地創建和管理線程。其常用的函數有 QtConcurrent::run()、QtConcurrent::map()、QtConcurrent::filter() 等,可用于并行計算、數據處理等功能。

    • 例如,使用 QtConcurrent::run() 函數可以在一個新線程中執行一個普通函數或成員函數,該函數會自動在后臺線程中運行,無需手動創建線程和處理線程同步等問題。

多線程的核心原理

  • 事件循環 :每個線程都有自己的事件循環,用于處理該線程中的事件,如信號槽調用、定時器事件等。主線程的事件循環由 QApplication 或 QCoreApplication 啟動,子線程可以通過調用 exec() 函數啟動事件循環。

  • 信號槽通信 :是 Qt 多線程間通信的核心機制。跨線程時,信號會被自動轉為 “事件” 放入目標線程的事件循環中執行,從而實現線程間的安全通信。例如,子線程通過發出信號將采集到的數據傳遞給主線程,主線程接收到信號后在對應的槽函數中更新 UI。

多線程開發的注意事項

  • 避免直接操作 UI :子線程不能直接操作 UI 控件,所有 UI 操作都必須通過信號槽傳遞到主線程中進行。

  • 線程安全 :如果多個線程需要訪問同一變量或資源,需使用 QMutex 或 QReadWriteLock 等互斥鎖來保護共享數據,避免出現競態條件和數據不一致的問題。

  • 正確退出線程 :應使用標志位控制循環退出,而不是強制調用 terminate() 函數,以確保線程能夠安全、優雅地終止。并在 QThread::finished 信號中刪除相關對象,避免內存泄漏。

  • 信號槽連接類型 :需要明確信號槽的連接類型,跨線程時建議使用 Qt::QueuedConnection,同線程時可使用 Qt::DirectConnection,默認情況下 Qt 會自動判斷連接類型。

多線程的應用場景

  • UI 響應優化 :將耗時的計算、數據處理、文件讀寫等操作放到子線程中執行,確保主線程能夠快速響應用戶的操作,保持界面的流暢性。

  • 異步數據加載 :在網絡應用中,數據的加載和傳輸通常需要較長時間,通過多線程可以實現異步加載數據,避免阻塞 UI,提升用戶體驗。

  • 并發處理任務 :在需要同時處理多個任務時,如同時處理多個設備的數據采集、多個文件的壓縮或解壓縮等,可以使用多線程來提高任務的執行效率。

  • 圖形圖像處理 :對于復雜的圖形圖像處理任務,如圖像的渲染、濾鏡效果的實現等,可以將這些任務分配到多個線程中并行處理,以加速處理過程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82056.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82056.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82056.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于ITcpServer/IHttpServer框架的HTTP服務器

https://www.cnblogs.com/MuZhangyong/p/16839231.html 在基于ITcpServer/IHttpServer框架的HTTP服務器實現中,OnBody方法主要用于接收HTTP請求體數據,而觸發HTTP響應通常是在OnMessageComplete方法中完成。以下是完整的響應觸發機制說明: sequenceDiagramClient->>…

Windows 下 Qt 項目配置 FFmpeg 簡明指南

一、作用 在qt項目中配置ffmpeg庫 二、步驟 1、直接使用已經編譯好的ffmpeg庫文件,分為win32版本和win64版本; 2、win32版本下載地址:https://github.com/sudo-nautilus/FFmpeg-Builds-Win32/releases/tag/latest 3、win64版本下載地址&a…

Attu下載 Mac版與Win版

通過Git地址下載 Mac 版選擇對于的架構進行安裝 其中遇到了安裝不成功,文件損壞等問題 一般是兩種情況導致 1.安裝版本不對 2.系統權限限制 https://www.cnblogs.com/similar/p/11280162.html打開terminal執行以下命令 sudo spctl --master-disable安裝包Git下載地…

SpringBoot3集成Oauth2.1——5資源地址配置

配置問題說明 如下所示,代碼配置了兩個,過濾器,一個是資源保護,一個是不保護。 /** Description: 配置需要保護的資源* author: 胡濤* mail: hutao_2017aliyun.com* date: 2025年5月23日 下午2:28:20*/BeanOrder(2)public Securi…

Python urllib.parse 模塊中的 urljoin 方法

Python urllib.parse 模塊中的 urljoin 方法 urljoin 是 Python 標準庫中 urllib.parse 模塊的一個方法,用于將基礎 URL 和相對路徑拼接成完整的 URL。它會根據傳入的基礎 URL 自動處理協議、域名以及路徑的部分匹配邏輯。 以下是關于該方法的具體說明和示例&…

AI大模型和SpringAI簡介

一、Spring AI 簡介 SpringAI整合了全球(主要是國外)的大多數大模型,而且對于大模型開發的三種技術架構都有比較好的封裝和支持,開發起來非常方便。 不同的模型能夠接收的輸入類型、輸出類型不一定相同。SpringAI根據模型的輸入…

在TIA 博途中下載程序時找不到對應的網卡怎么辦?

1. 檢查物理連接 確認網線已正確連接PLC和PC,接口指示燈正常。 嘗試更換網線或交換機端口,排除硬件故障。 2. 確認網卡驅動已安裝 設備管理器檢查: 右鍵點擊“此電腦” → “管理” → “設備管理器”。 展開“網絡適配器”,確…

Zabbix實踐!客戶端自動發現

在線答疑:樂維社區 一、客戶端狀態檢查 1.檢查客戶端的zabbix-agent2是否正常 [rootnode1 ~]# systemctl is-active zabbix-agent2.service active 2.從服務端檢查是否可以獲得客戶端信息 [rootIT-01 ~]# zabbix_get -s ‘192.168.200.135’ -p 10050 -k ‘agent.p…

動態規劃中的 求“最長”、“最大收益”、“最多區間”、“最優策略” 雙重 for + 狀態轉移

以最長遞增子序列為例 🎯 首先明確目標 以最長上升子序列(LIS)為例,假設輸入是: nums : []int{10, 9, 2, 5, 3, 7, 101, 18}我們定義: dp[i]:以 nums[i] 為結尾的最長上升子序列長度目標&…

SEO關鍵詞與長尾詞高效布局

內容概要 在SEO優化實踐中,關鍵詞布局的科學性與系統性直接影響流量的獲取效率與可持續性。本文以核心關鍵詞篩選為起點,結合長尾詞挖掘工具與語義關聯分析技術,逐步構建覆蓋用戶全搜索場景的內容矩陣。通過金字塔結構模型,實現高…

考研數一公式筆記

考研數學(一)核心結論與易錯點詳細筆記 第一部分:高等數學 一、函數、極限、連續 (一) 重要結論與公式 等價無窮小替換 (僅限乘除運算,極限過程為 x → 0 或某特定值導致因子→0): sin x ~ x tan x ~ x arcsin x …

Debezium TableSchemaBuilder詳解

Debezium TableSchemaBuilder詳解 1. 類的作用與功能 1.1 核心作用 TableSchemaBuilder是Debezium中負責構建表Schema的核心類,主要功能包括: Schema構建:將數據庫表結構轉換為Kafka Connect的Schema定義主鍵處理:生成表的主鍵Schema值Schema處理:生成表的非主鍵字段Sc…

49 python Matplotlib之Pandas 數據可視化

Pandas 是 Python 中用于數據處理的核心庫,其內置了基于 Matplotlib 的可視化功能,可通過 DataFrame.plot() 和 Series.plot() 方法快速生成常見圖表,無需手動編寫繪圖代碼,大幅提升效率。 一、Pandas 核心繪圖方法 基礎語法如下:該代碼為偽代碼,僅做語法說明,無法執行…

《微服務架構設計模式》筆記

思維導圖 1-3章 4-6 章 5-13 章 資料 配套代碼倉庫:https://github.com/microservices-patterns/ftgo-application 作者網站:https://microservices.io/

手寫一個簡單的線程池

手寫一個簡單的線程池 項目倉庫:https://gitee.com/bossDuy/hand-tearing-thread-pool 基于一個b站up的課程:https://www.bilibili.com/video/BV1cJf2YXEw3/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 理…

手機打電話時由對方DTMF響應切換多級IVR語音菜單(完結)

手機打電話時由對方DTMF響應切換多級IVR語音菜單(完結) --本地AI電話機器人 上一篇:手機打電話時由對方DTMF響應切換多級IVR語音菜單(話術腳本與實戰) 下一篇:編寫中 一、前言 經過前面幾個篇章的詳細闡…

Android.mk解析

一、變量說明: 1.LOCAL_PATH:= $(call my-dir) 此行代碼在Android.mk的開頭,用于給出當前文件的路徑 LOCAL_PATH 用于在開發樹中查找源文件 宏函數’my-dir’, 由編譯系統提供,用于返回當前路徑(即包含Android.mk file文件的目錄) 2.LOCAL_PACKAGE_NAME := SecSettings …

ip地址改了網絡還能用嗎?ip地址改了有什么后果

當用戶發現自己的網絡出現異常時,常常會疑惑:如果IP地址被更改,網絡是否還能正常使用?要解答這個問題,需要從IP地址的作用、修改方式以及網絡配置等多個角度來分析。 一、IP地址的作用 IP地址是設備在網絡中的唯一標識…

Python-Django系列—日志

Python 程序員通常會在其代碼中使用 print() 作為一種快速和方便的調試工具。使用日志框架只比這多花一點點工夫,但更加優雅和靈活。除了用于調試之外,日志還可以為您提供有關應用程序狀態和健康狀況的更多信息,而且這些信息結構更清晰。 一…

ArcGIS Pro對圖斑進行等比例、等面積、等寬度的分割

ArcGIS全系列實戰視頻教程——9個單一課程組合系列直播回放_arcgis視頻教程我要自學網-CSDN博客 4大遙感軟件!遙感影像解譯!ArcGISENVIErdaseCognition_遙感解譯軟件-CSDN博客 今天介紹一下ArcGIS Pro對圖斑進行等比例、等面積、等寬度的分割&#xff0…