概 述
Qt中提供了QSharedMemory
類來實(shí)現(xiàn)共享內(nèi)存相關(guān)的操作,本文介紹Qt中QSharedMemory
類的常用函數(shù)以及具體的實(shí)現(xiàn)助隧。
頭文件 #include <QSharedMemory>
常用函數(shù)
一、類的創(chuàng)建
- 構(gòu)造函數(shù)
QSharedMemory(const QString &key, QObject *parent = nullptr)
key為共享內(nèi)存的關(guān)鍵字,想要操作同一塊共享內(nèi)存需要key一致
QSharedMemory* m_shareMemory;
m_shareMemory= new QSharedMemory("SharedMemory_Key");
- 構(gòu)造函數(shù)
QSharedMemory(QObject *parent = nullptr)
構(gòu)造實(shí)例對象后彼哼,調(diào)用setKey()
函數(shù)來設(shè)置關(guān)鍵字
QSharedMemory* m_shareMemory;
m_shareMemory = new QSharedMemory();
m_shareMemory->setKey("SharedMemory_Key");
注:只有設(shè)置了key迹淌,才可以調(diào)用create()
和attach()
函數(shù)河绽。
二、創(chuàng)建共享內(nèi)存
//為傳遞給構(gòu)造函數(shù)的key創(chuàng)建大小為size的共享內(nèi)存段唉窃,成功返回true耙饰,反之false
bool QSharedMemory::create(int size, AccessMode mode = ReadWrite)
size
:創(chuàng)建共享內(nèi)存的大小
mode
:內(nèi)存的訪問方式,默認(rèn)為可讀可寫纹份。QSharedMemory
類定義一個枚舉類變量AccessMode
苟跪,指定了兩種共享內(nèi)存的訪問方式:
-
QSharedMemory::ReadOnly
只讀方式訪問共享內(nèi)存 -
QSharedMemory::ReadWrite
讀寫方式訪問共享內(nèi)存
三、附加/分離共享內(nèi)存
附加:將當(dāng)前進(jìn)程附加到以關(guān)鍵字為key的共享內(nèi)存蔓涧,默認(rèn)的訪問方式為可讀可寫件已。只有附加的共享內(nèi)存才能讀取其內(nèi)存數(shù)據(jù)。
bool QSharedMemory::attach(AccessMode mode = ReadWrite)
分離:將以關(guān)鍵字為key的共享內(nèi)存分離進(jìn)程元暴,分離后篷扩,進(jìn)程將不再能訪問共享內(nèi)存。如果這是附加到共享內(nèi)存段的最后一個進(jìn)程昨寞,則共享內(nèi)存段由系統(tǒng)釋放瞻惋,即內(nèi)容被銷毀。
bool QSharedMemory::detach()
四援岩、鎖定/解鎖共享內(nèi)存
bool QSharedMemory::lock() //鎖定共享內(nèi)存
bool QSharedMemory::unlock() //解鎖共享內(nèi)存
用法與常見的鎖一樣歼狼,訪問共享內(nèi)存之前鎖定,訪問結(jié)束后解鎖享怀。
由于需要人為手動解鎖羽峰,這里不建議使用這種方式,可以使用RAII機(jī)制的lock_guard
來實(shí)現(xiàn)自動的加鎖、解鎖
五梅屉、其他
QString QSharedMemory::key() const //獲取共享內(nèi)存關(guān)鍵字
void QSharedMemory::setKey(const QString &key) //設(shè)置共享內(nèi)存關(guān)鍵字
bool QSharedMemory::isAttached() const //判斷共享內(nèi)存的附加狀態(tài)
void * QSharedMemory::data() //獲取共享內(nèi)存的內(nèi)存地址
實(shí) 現(xiàn)
ShareMemA.h
#ifndef SHAREMEMA_H
#define SHAREMEMA_H
#include <QObject>
#include <QSharedMemory>
class ShareMemA : public QObject
{
Q_OBJECT
public:
ShareMemA();
virtual ~ShareMemA();
private:
QSharedMemory* m_sharedMemmory;
void sharedMemmory();
};
#endif // SHAREMEMA_H
ShareMemA.cpp
#include "ShareMemA.h"
#include <mutex>
#include <QDebug>
#include <QSharedMemory>
ShareMemA::ShareMemA():
m_sharedMemmory(new QSharedMemory(this))
{
m_sharedMemmory->setKey("SharedMemory_Key");
sharedMemmory();
}
ShareMemA::~ShareMemA()
{
}
void ShareMemA::sharedMemmory()
{
if (m_sharedMemmory->isAttached()) {
if(!m_sharedMemmory->detach())
qDebug() << "detach error";
return;
}
if (m_sharedMemmory->create(1024)) {
qDebug () <<"create sharedMemmory success";
std::lock_guard<QSharedMemory> lock(*m_sharedMemmory);
const char* data = (char*)m_sharedMemmory->data();
data = "hello";
memcpy(m_sharedMemmory->data(), data, strlen(data)*sizeof(char));
}
}
ShareMemB.h
#ifndef SHAREMEMB_H
#define SHAREMEMB_H
#include <QObject>
#include <QSharedMemory>
class ShareMemB : public QObject
{
Q_OBJECT
public:
ShareMemB();
virtual ~ShareMemB();
private:
QSharedMemory* m_sharedMemmory;
void sharedMemmory();
};
#endif // SHAREMEMB_H
ShareMemB.h
#include "ShareMemB.h"
#include <mutex>
#include <QDebug>
#include <QSharedMemory>
ShareMemB::ShareMemB():
m_sharedMemmory(new QSharedMemory(this))
{
m_sharedMemmory->setKey("SharedMemory_Key");
sharedMemmory();
}
ShareMemB::~ShareMemB()
{
}
void ShareMemB::sharedMemmory()
{
std::lock_guard<QSharedMemory> lock(*m_sharedMemmory);
if (!m_sharedMemmory->attach()) {
qDebug()<<"attach error!";
return;
}
char *data = (char *)m_sharedMemmory->data();
qDebug() << "read sharememmory data: " << data;
m_sharedMemmory->detach();
}