Qt進程間通信:QSharedMemory 使用詳解

1. 什么是 QSharedMemory?

QSharedMemory?是 Qt 中用于進程間共享內存的類。它允許多個進程共享一塊內存區域,從而避免數據傳輸時的 IO 操作,提高通信速度。通過共享內存,多個進程可以直接讀寫這塊內存,而無需經過文件或網絡傳遞。

QSharedMemory 的核心特點

  1. 唯一鍵(Key)標識

    • 每塊共享內存通過唯一的鍵(字符串)標識。

    • 不同進程通過相同的鍵連接到共享內存。

  2. 線程安全性

    • 提供鎖機制(lock()?和?unlock())以保護共享內存的讀寫。

  3. 跨平臺支持

    • Qt 的跨平臺特性使?QSharedMemory?可以在不同操作系統上無縫使用。


2. QSharedMemory 的常用場景

  1. 實時數據共享

    • 如傳感器數據、實時日志等需要在多個進程間快速傳遞。

  2. 高性能需求

    • 在頻繁更新的大量數據(如圖像處理、緩存共享)中,通過共享內存減少通信開銷。

  3. 進程間消息傳遞

    • 兩個或多個應用程序之間的簡單數據交換。


3. QSharedMemory 的工作流程

共享內存的基本使用可以分為以下幾個步驟:

  1. 創建共享內存

    • 第一個進程通過?create(size)?創建一塊共享內存。

    • 分配的大小由數據的存儲需求決定。

  2. 附加到共享內存

    • 其他進程通過?attach()?方法連接到已有的共享內存。

  3. 數據讀寫

    • 通過?lock()?和?unlock()?保證線程安全,獲取內存指針后讀寫數據。

  4. 釋放共享內存

    • 調用?detach()?斷開與共享內存的連接。


4. QSharedMemory 常用函數詳解

以下是?QSharedMemory?類的常用函數及其作用:

函數名作用
構造函數

創建?QSharedMemory?對象,指定唯一鍵標識共享內存。

create(size)

創建指定大小的共享內存,如果共享內存已存在則返回失敗。

attach()

附加到已有的共享內存,連接成功后可以訪問內存內容。

detach()

斷開與共享內存的連接,并釋放資源(只有最后一個進程斷開時共享內存才會被銷毀)。

lock()

鎖定共享內存,防止其他進程或線程同時訪問數據(用于數據同步)。

unlock()

解鎖共享內存,允許其他進程訪問數據。

data()

?/?constData()

獲取共享內存的指針,用于讀寫數據(data()?為可寫指針,constData()?為只讀指針)。

isAttached()

檢查當前進程是否已經連接到共享內存。

error()

?/?errorString()

獲取最近一次操作的錯誤代碼和描述,便于調試。


5. 使用示例:QSharedMemory 實現進程間通信

以下是一個完整的例子,展示如何通過?QSharedMemory?實現進程間的讀寫通信。

程序1:寫入共享內存

程序1負責創建共享內存并向其中寫入數據。

#include?<QCoreApplication>
#include?<QSharedMemory>
#include?<QDebug>
#include?<QTimer>
#include?<QDateTime>#define?tc(a) QString::fromLocal8Bit(a)int?main(int?argc,?char?*argv[])
{QCoreApplication?a(argc, argv);QSharedMemory?sharedMemory("MySharedMemoryKey");// 創建共享內存,大小為 1024 字節if?(!sharedMemory.create(1024)) {qDebug() << tc("無法創建共享內存:") << sharedMemory.errorString();return-1;}qDebug() << tc("共享內存已創建");// 定時寫入動態數據QTimer timer;QObject::connect(&timer, &QTimer::timeout, [&]() {if?(sharedMemory.lock()) {char?*to =?static_cast<char?*>(sharedMemory.data());QString message = tc("程序1動態消息#") + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");QByteArray byteArray = message.toLocal8Bit();memcpy(to, byteArray.data(), byteArray.size() +?1);?// 寫入動態數據sharedMemory.unlock();qDebug() << tc("成功寫入共享內存:") << message;}?else?{qDebug() << tc("無法鎖定共享內存進行寫入:") << sharedMemory.errorString();}});timer.start(1000);?// 每秒更新一次return?a.exec();
}

程序2:讀取共享內存

程序2連接到共享內存,讀取數據并解析時間戳。

#include?<QCoreApplication>
#include?<QSharedMemory>
#include?<QDebug>
#include?<QTimer>
#include?<QDateTime>#define?tc(a) QString::fromLocal8Bit(a)int?main(int?argc,?char?*argv[])
{QCoreApplication?a(argc, argv);QSharedMemory?sharedMemory("MySharedMemoryKey");// 連接到已有的共享內存if?(!sharedMemory.attach()) {qDebug() << tc("無法連接到共享內存:") << sharedMemory.errorString();return-1;}qDebug() << tc("成功連接到共享內存");// 定時讀取數據QTimer timer;QObject::connect(&timer, &QTimer::timeout, [&]() {if?(sharedMemory.lock()) {constchar?*from =?static_cast<constchar?*>(sharedMemory.constData());QString data = QString::fromLocal8Bit(from);sharedMemory.unlock();// 解析時間戳QString timeStampString = data.split("#").at(1);QDateTime messageTime = QDateTime::fromString(timeStampString,?"yyyy-MM-dd hh:mm:ss.zzz");// 當前時間QDateTime currentTime = QDateTime::currentDateTime();qDebug() << tc("從共享內存讀取到的數據:") << data;// 如果時間戳解析成功,計算時間差if?(messageTime.isValid()) {qint64 timeDifference = messageTime.msecsTo(currentTime);?// 時間差(毫秒)qDebug() << tc("接收到的時間:") << messageTime.toString("yyyy-MM-dd hh:mm:ss.zzz");qDebug() << tc("當前時間:") << currentTime.toString("yyyy-MM-dd hh:mm:ss.zzz");qDebug() << tc("時間差(毫秒):") << timeDifference;}?else?{qDebug() << tc("無法解析時間戳!");}}?else?{qDebug() << tc("無法鎖定共享內存進行讀取:") << sharedMemory.errorString();}});timer.start(1000);?// 每秒讀取一次return?a.exec();
}


6. 注意事項

  1. 共享內存大小

    • 創建共享內存時,指定的大小必須足夠大以存儲所有數據。

  2. 鎖機制

    • 在操作共享內存前,必須調用?lock()?進行鎖定,以避免數據競爭。

    • 使用完成后,必須調用?unlock()?解鎖。

  3. 錯誤處理

    • 使用?error()?和?errorString()?檢查共享內存的狀態。

  4. 進程退出

    • 調用?detach()?確保釋放共享內存資源。


7. 總結

QSharedMemory?是一種高效的進程間通信方式,適用于需要快速傳遞數據的場景。通過本文的講解,您應該能夠掌握?QSharedMemory?的核心功能及其應用。無論是共享日志、實時數據,還是跨進程消息傳遞,QSharedMemory?都是一個值得考慮的解決方案。

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

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

相關文章

2024年3月全國計算機等級考試真題(二級C語言)

&#x1f600; 第1題 下列敘述中正確的是 A. 矩陣是非線性結構 B. 數組是長度固定的線性表 C. 對線性表只能作插入與刪除運算 D. 線性表中各元素的數據類型可以不同 題目解析&#xff1a; A. 矩陣是非線性結構 錯誤。矩陣通常是二維數組&#xff0c;屬…

基于Ebay拍賣網站成交價格的影響因素分析

摘要:近些年來網上拍賣的不斷地發展&#xff0c;網上購物慢慢變成了大家普遍接受的購物方式。因此關于網上拍賣的研究日益成為很多人研究的重點。 影響拍賣網站價格的因素很多&#xff0c;但很少有人分得清楚哪些因素才是比較重要的因素&#xff0c;因此對價格因素分析&#x…

Langchain中的表格解析:RAG 和表格的愛恨情仇

實現 RAG(Retrieval-Augmented Generation)是一個挑戰,尤其是在有效解析和理解非結構化文檔中的表格時。這在處理掃描文檔或圖像格式的文檔時尤為困難。這些挑戰至少包括以下三個方面: 1.表格的“叛逆期”:不準確的解析可能會破壞表格結構: 表格在文檔里就像個叛逆的青少…

Solr-搜索引擎-入門到精通

以下是對 Apache Solr 的簡介及其常用語法的快速入門指南&#xff1a; 一、Solr 是什么&#xff1f; ? 核心定位&#xff1a;Apache Solr 是一個基于 Lucene 的高性能、開源的搜索平臺&#xff0c;支持全文檢索、分詞、高亮、聚合統計等功能。 ? 核心功能&#xff1a; ? 全…

原生后臺GPS位置限制,降低功耗

1.后臺 GPS 位置限制的背景 為了控制功耗&#xff0c;Android 平臺對后臺應用獲取位置信息的頻率進行了限制。后臺的定義與后臺執行限制一致&#xff0c;即應用不在前臺運行時被視為后臺應用。 2.更新間隔限制&#xff1a; 后臺應用獲取位置信息的更新間隔不能超過一定閾值。…

Docker 搭建 PlantUML 服務:高效生成 UML 圖的最佳實踐

PlantUML 是一款開源的 UML 圖形生成工具&#xff0c;它支持生成類圖、時序圖、用例圖、活動圖等多種類型的 UML 圖&#xff0c;廣泛應用于軟件設計、文檔編寫以及團隊溝通中。通過 Docker 安裝 PlantUML&#xff0c;開發者可以快速搭建環境&#xff0c;輕松生成 UML 圖&#x…

簡鹿辦公匯總快速打開 Windows 資源管理器的幾種方式

無論你是剛開始使用電腦的新手&#xff0c;還是已經有一定經驗的用戶&#xff0c;了解如何在 Windows 系統中打開資源管理器都是一個非常基本且重要的技能。Windows 資源管理器&#xff08;現在稱為“文件資源管理器”&#xff09;是幫助你瀏覽、查找和管理計算機上所有文件的主…

嵌入式 python 安裝

下載嵌入式Python后解壓 https://www.python.org/ftp/python/3.12.9/python-3.12.9-embed-amd64.zip cd python-3.12.9-embed-amd64 安裝 pip .\python.exe .\get-pip.py 放開限制 嵌入式 Python 為了減少體積&#xff0c;默認會有一些限制。你需要編輯 python312._pth 文…

DeepSeek底層揭秘——GEMM

目錄 1. 什么是 GEMM&#xff1f; (1) 定義 (2) 核心目標 2. 核心功能 3. 對比傳統通用矩陣乘法庫 4. 技術要素 (1) 硬件感知優化 (2) 自動調優 (3) 高效內存管理 (4) 混合精度計算 5. 難點挑戰&#xff08;含解決方案&#xff09; 6. 技術路徑 7. 具體技術實現 8…

DNA-PAINT

參考: 【科研教程】NUPACK網頁版使用教程 https://www.bilibili.com/video/BV1G94y1W7mN/NUPACK新版網頁版教程-模擬部分 https://zhuanlan.zhihu.com/p/678730568NUPACK 4.0 User Guide https://docs.nupack.org/NUPACK網頁版使用指南 https://zhuanlan.zhihu.com/p/55024017…

小程序內表格合并功能實現—行合并

功能介紹&#xff1a;支付寶小程序手寫表格實現行內合并&#xff0c;依據動態數據自動計算每次需求合并的值&#xff0c;本次記錄行內合并&#xff0c;如果列內合并&#xff0c;同理即可實現 前端技術&#xff1a;grid布局 display&#xff1a;grid 先看實現效果: axml&…

計算機視覺cv2入門之角點檢測

角點是指圖像中兩條邊緣線的交點&#xff0c;這些交點通常代表了圖像中的重要特征。在計算機視覺中&#xff0c;角點檢測是一種關鍵的技術&#xff0c;它可以幫助我們從圖像中提取出這些重要的特征點&#xff0c;進而用于圖像匹配、物體識別、圖像拼接等多種應用。 角點檢測示例…

抽獎的誘惑系統注冊與登錄功能測試報告

目錄 一&#xff1a;項目背景 二&#xff1a;項目功能 &#xff08;1&#xff09; 注冊功能 &#xff08;2&#xff09; 登錄功能 電話 密碼登錄 電話 短信登錄 三&#xff1a;設計測試用例 四&#xff1a;功能測試 五&#xff1a;自動化測試代碼 七&#xff1a;遺留風…

【多媒體交互】Unity Kinect實現UI控件的點擊

在Unity中&#xff0c;通過Kinect實現UI控件的點擊功能&#xff0c;主要涉及手部追蹤、坐標映射和手勢檢測三個核心環節。 實現步驟 初始化Kinect與關節追蹤 使用KinectManager獲取用戶ID和手部關節點&#xff08;如JointType.HandLeft&#xff09;的坐標。 long userId _…

【藍橋杯】每日練習 Day12 貢獻法

前言 今天給大家帶來兩道貢獻法的問題&#xff0c;先來講一下什么是貢獻法。 貢獻法&#xff0c;與其說是一種算法&#xff0c;不如說是一種數學方法&#xff0c;是一種思維方式。 先來給大家舉個例子&#xff0c;假設現在有個問題&#xff0c;需要你在一個只有小寫字母的字…

go test相關命令

在 Go 項目中&#xff0c;go test 可以用于運行整個工程中的測試文件。以下是幾種方式&#xff1a; 1. 運行當前模塊或整個工程的測試 go test ./..../... 表示遞歸測試所有子目錄中的測試文件&#xff08;*_test.go&#xff09;。適用于 Go Modules 或 GOPATH 結構的項目。 …

RocketMQ 詳細知識點總結

RocketMQ 詳細知識點總結 1. 核心概念 1.1 基礎組件 Producer(生產者) 消息的發送者支持同步、異步和單向發送方式提供事務消息功能Consumer(消費者) 消息的接收者支持Push和Pull兩種消費模式支持集群消費和廣播消費NameServer(命名服務) 路由注冊中心無狀態節點,可集…

文字也能生成視頻?【藍耘實踐】:通義萬相2.1文生視頻

文字也能生成視頻&#xff1f;【藍耘實踐】&#xff1a;通義萬相2.1文生視頻 上次我們已經介紹了關于在藍耘云平臺實踐通義萬相的基本玩法&#xff0c;這次將介紹進階玩法&#xff0c;也就是使用文字來生成視頻。 首先我們還是先注冊或者登錄藍耘云平臺。 通過藍耘平臺進入流…

藍橋杯 跑步計劃

問題描述 小藍計劃在某天的日期中出現 1 時跑 5 千米&#xff0c;否則只跑 1 千米。注意&#xff1a;日期中出現 1 不僅指年月日&#xff0c;也指星期。 請問按照小藍的計劃&#xff0c;2023 年小藍總共會跑步鍛煉多少千米&#xff1f; 例如&#xff1a; 5 月 1 日1 月 13 …

K8S集群新增和刪除Node節點(K8s Cluster Adds and Removes Node Nodes)

實戰&#xff1a;在已有K8S集群如何新增和刪除Node節點 在Kubernetes (K8S) 集群中&#xff0c;Node節點是集群中的工作節點&#xff0c;它們運行著容器的實際實例。管理K8S集群中的Node節點&#xff0c;包括新增和刪除節點&#xff0c;是一個常見且重要的操作&#xff0c;可以…