【Qt】QSharedMemory类详解
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 公有類型
- 03. 成員方法
- 04. 程序示例一
- 05. 程序示例二
- 06. 源碼下載
- 07. 附錄
01. 概述
QSharedMemory提供了多個線程和進程對共享內存段的訪問。它還提供了一種方法,讓單個線程或進程鎖定內存以進行獨占訪問。
當使用這個共享內存類時,請注意以下平臺差異:
Windows:QSharedMemory 不“擁有”共享內存段。當所有具有連接到特定共享內存段的 QSharedMemory 實例的線程或進程已銷毀其 QSharedMemory 實例或退出時,Windows 內核會自動釋放共享內存段。
Unix:QSharedMemory“擁有”共享內存段。當將 QSharedMemory 實例附加到特定共享內存段的最后一個線程或進程通過銷毀其 QSharedMemory 實例與該段分離時,Unix 內核會釋放共享內存段。但是如果最后一個線程或進程在沒有運行 QSharedMemory 析構函數的情況下崩潰,共享內存段會在崩潰中幸存下來。
HP-UX:每個進程只允許一個連接到共享內存段。這意味著 QSharedMemory 不應跨 HP-UX 中同一進程中的多個線程使用。
記得在對共享內存進行讀寫之前用lock ()鎖住共享內存,完成后記得用unlock ()釋放鎖。
當 QSharedMemory 的最后一個實例與段分離時,QSharedMemory 會自動銷毀共享內存段,并且不會保留對該段的引用。
警告
除非另有說明,否則 QSharedMemory 以特定于 Qt 的方式更改密鑰。與非 Qt 應用程序的互操作是通過首先使用 QSharedMemory() 創建默認共享內存,然后使用 setNativeKey() 設置本機密鑰來實現的。使用本機密鑰時,共享內存不受對其多次訪問的保護(例如,無法鎖定()),應使用用戶定義的機制來實現這種保護。
02. 公有類型
03. 成員方法
成員方法概述
QSharedMemory::QSharedMemory(const QString &key, QObject *parent = nullptr) 使用給定的父對象構造一個共享內存對象,并將其鍵設置為key。因為它的key被設置了,它的create ()和 attach ()函數就可以調用了。 QSharedMemory::QSharedMemory(QObject *parent = nullptr) 此函數重載 QSharedMemory()。 使用給定的parent構造一個共享內存對象。共享內存對象的鍵不是由構造函數設置的,因此共享內存對象沒有附加底層共享內存段。 在調用`create()`或者attach()之前必須使用setKey()或者setNativeKey()設置Key.[virtual] QSharedMemory::~QSharedMemory() 析構函數清除Key,這會強制共享內存對象與其底層共享內存段分離。如果此共享內存對象是最后一個連接到共享內存段的對象, 則detach () 操作會銷毀共享內存段。bool QSharedMemory::attach(QSharedMemory::AccessMode mode = ReadWrite) 嘗試將進程關聯到由傳遞給構造函數或調用setKey () 或setNativeKey ()的密鑰標識的共享內存段。 訪問方式默認為ReadWrite。 它也可以是ReadOnly。true如果附加操作成功則返回。如果返回false,則調用error ()來判斷發生了哪個錯誤。 附加共享內存段后, 可以通過調用data ()獲得共享內存的指針。 const void *QSharedMemory::constData() const 返回一個指向共享內存段內容的常量指針,如果有的話。否則返回空值。記得在對共享內存進行讀寫之前用lock ()鎖住共享內存, 完成后記得用unlock ()釋放鎖。bool QSharedMemory::create(int size, QSharedMemory::AccessMode mode = ReadWrite) 使用傳遞給構造函數的鍵創建大小為size字節的共享內存段,使用setKey () 或使用setNativeKey ()設置key, 然后使用給定的訪問模式 關聯到新的共享內存段并返回true。如果key標識的共享內存段已經存在,則不執行attach操作并false返回。當返回值為 時false, 調用error ()來判斷發生了哪個錯誤。 void *QSharedMemory::data() 返回一個指向共享內存段內容的指針,如果有的話。否則返回空值。記得在對共享內存進行讀寫之前用lock ()鎖住共享內存, 完成后記得用unlock ()釋放鎖。const void *QSharedMemory::data() const 此函數重載 data()。bool QSharedMemory::detach() 從共享內存段中分離進程。如果這是最后一個附加到共享內存段的進程,那么共享內存段將被系統釋放,即內容被銷毀。 true如果它分離共享內存段,則該函數返回。如果它返回false,通常意味著該段沒有被附加,或者它被另一個進程鎖定。QSharedMemory::SharedMemoryError QSharedMemory::error() const 返回一個值,該值指示是否發生了錯誤,如果發生了,則是哪個錯誤。QString QSharedMemory::errorString() const 返回最后發生的錯誤的文本描述。如果error () 返回錯誤值,則調用此函數以獲取描述錯誤的文本字符串。bool QSharedMemory::isAttached() const 返回true此進程是否附加到共享內存段。QString QSharedMemory::key() const 返回用setKey ()分配給這個共享內存的鍵,如果沒有分配鍵,或者段使用nativeKey () ,則返回空鍵。 密鑰是 Qt 應用程序用來標識共享內存段的標識符。您可以通過調用nativeKey ()找到操作系統使用的本機、特定于平臺的key。 bool QSharedMemory::lock() 這是一個信號量,它鎖定共享內存段以供此進程訪問并返回true。如果另一個進程鎖定了該段,則該函數將阻塞, 直到鎖定被釋放。然后它獲取鎖并返回true。如果此函數返回false,則表示您忽略了來自create () 或attach () 的 false 返回,您已使用setNativeKey ()設置key或QSystemSemaphore::acquire () 由于未知系統錯誤而失敗。 QString QSharedMemory::nativeKey() const 返回此共享內存對象的本機、特定于平臺的key。本機key是操作系統用來標識共享內存段的標識符。 您可以使用本機key訪問不是由 Qt 創建的共享內存段,或授予非 Qt 應用程序共享內存訪問權限。 void QSharedMemory::setKey(const QString &key) 為這個共享內存對象設置平臺無關的鍵。如果key與當前 key 相同,則函數不執行任何操作就返回。 您可以調用key () 來檢索平臺無關的密鑰。在內部,QSharedMemory將此密鑰轉換為特定于平臺的密鑰。 如果您改為調用nativeKey (),您將獲得特定于平臺的轉換后的密鑰。 如果共享內存對象附加到底層共享內存段,它將在設置新密鑰之前與其分離。這個函數不做attach ()。void QSharedMemory::setNativeKey(const QString &key) 設置此共享內存對象的本機、特定于平臺的鍵。如果key與當前本機 key 相同,則該函數不執行任何操作就返回。 如果您只想為段分配一個鍵,則應改為調用setKey ()。 您可以調用nativeKey () 來檢索本機密鑰。如果已分配本機鍵,則調用key () 將返回空字符串。 如果共享內存對象附加到底層共享內存段,它將在設置新密鑰之前與其分離。這個函數不做attach ()。 如果您設置本機密鑰,該應用程序將不可移植。int QSharedMemory::size() const 返回附加共享內存段的大小。如果沒有附加共享內存段,則返回 0。 注意:段的大小可能大于傳遞給create ()的請求大小。bool QSharedMemory::unlock() 如果該進程當前持有該鎖,則釋放共享內存段上的鎖并返回true。如果該段沒有被鎖定,或者如果該鎖定被另一個進程持有, 則什么都不會發生并且返回 false。04. 程序示例一
程序示例
#include <QCoreApplication>#include <QSharedMemory> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);//共享內存對象QSharedMemory shareMemory;//設置共享內存的鍵 沒有設置key之前默認為空qDebug() << "Key: " << shareMemory.key();//設置共享內存的KeyshareMemory.setKey("Qt");qDebug() << "Key: " << shareMemory.key();//默認共享內存是沒有關聯的qDebug() << "isAttached: " << shareMemory.isAttached();//對應Key的共享內存不存在,因此關聯失敗qDebug() << shareMemory.attach();qDebug() << shareMemory.errorString();//判斷該進程是否與共享內存關聯if (shareMemory.isAttached()){if (!shareMemory.detach()){qDebug() << shareMemory.errorString();return -1;}}//默認讀寫的方式創建共享內存 創建的同時自動關聯到該共享內存if (!shareMemory.create(1024)){qDebug() << shareMemory.errorString();return -1;}qDebug() << "isAttached: " << shareMemory.isAttached();qDebug() << "size: " << shareMemory.size();//加鎖qDebug() << "lock: " << shareMemory.lock();//獲取共享內存的起始地址void *data = shareMemory.data();qDebug() << "Addr: " << data;//拷貝數據memcpy(data, "hello", strlen("hello"));//解鎖qDebug() << "unlock: " << shareMemory.unlock();//解除與共享內存的關聯qDebug() << "detach: " << shareMemory.detach();return 0; }執行結果
Key: "" Key: "Qt" isAttached: false false "QSharedMemory::handle: doesn't exist" isAttached: true size: 4096 lock: true Addr: 0x29d0000 unlock: true detach: true05. 程序示例二
讀寫示例
#include <QCoreApplication>#include <QSharedMemory> #include <QDebug>/* 編程思路共享內存中數據提供方: A、定義QSharedMemory shareMemory,并設置標志名shareMemory.setKey(); B、將共享內存與主進程分離 shareMemory.detach(); C、創建共享內存 shareMemory.create(); D、將共享內存上鎖shareMemory.lock(); E、將進程中要共享的數據拷貝到共享內存中; F、將共享內存解鎖shareMemory.unlock();共享內存中數據使用方: A、定義QSharedMemory shareMemory,并設置與共享內存提供方一致的標志名shareMemory.setKey()。 B、將共享內存與主進程綁定shareMemory.attach(),使主進程可以訪問共享內存的數據; C、將共享內存上鎖shareMemory.lock(); D、從共享內存中取數據; E、使用完后將共享內存解鎖shareMemory.unlock(),并將共享內存與進程分離shareMemory.detach(); */int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);void *data = nullptr;const void *str = "好好學習,天天向上";//共享內存對象QSharedMemory shareMemory;//---------------寫共享內存-----------------//1. 設置共享內存keyshareMemory.setKey("Kitty");//2. 判斷進程是否與共享內存已經關聯,如果已經關聯就解除關聯if (shareMemory.isAttached()){if (!shareMemory.detach()){qDebug() << shareMemory.errorString();return -1;}else{qDebug() << "共享內存關聯成功";}}//3. 創建共享內存,同時關聯共享內存if (shareMemory.create(1024)){qDebug() << "創建共享內存成功";}else{qDebug() << shareMemory.errorString();return -1;}//4. 將共享內存上鎖shareMemory.lock();//5. 拷貝數據到共享內存data = shareMemory.data();if (nullptr == data){qDebug() << shareMemory.errorString();shareMemory.unlock();return -1;}memcpy(data, str, strlen(static_cast<const char *>(str)));//6.解鎖共享內存if (!shareMemory.unlock()){qDebug() << shareMemory.errorString();return -1;}//---------------讀共享內存-----------------//7. 將共享內存上鎖shareMemory.lock();data = nullptr;//8. 拷貝數據data = shareMemory.data();qDebug() << static_cast<char *>(data);//9. 解鎖共享內存if (!shareMemory.unlock()){qDebug() << shareMemory.errorString();return -1;}return 0; }執行結果
16:12:46: Starting D:\ProgramData\Qt\build-1TestShareMemrory-Desktop_Qt_5_15_2_MinGW_64_bit-Debug\ debug\1TestShareMemrory.exe ... 創建共享內存成功 好好學習,天天向上06. 源碼下載
下載:1TestShareMemrory.rar
07. 附錄
7.1 Qt教程匯總
網址:https://dengjin.blog.csdn.net/article/details/115174639
總結
以上是生活随笔為你收集整理的【Qt】QSharedMemory类详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Qt】Visual Studio编译Q
- 下一篇: 【Qt】进程间通信之QSharedMem