00. 目录
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();
//设置共享内存的Key
shareMemory.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: true
05. 程序示例二
读写示例
#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. 设置共享内存key
shareMemory.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. 源码下载
07. 附录
7.1 Qt教程汇总
网址:https://dengjin.blog.csdn.net/article/details/115174639
暂无评论内容