Qt 读写共享内存
一、简述
记--使用Qt进行简单的读写共享内存。
二、工程结构
三、测试代码
#include <QDebug>
#include <QSharedMemory>
//测试使用的数据结构
typedef struct{
int age;
char name[12];
}PeopleInfo_t;//注意考虑内存对齐,尽量凑为8的倍数,不够的添加保留位
//定义共享内存的大小
#define SHM_SIZE (sizeof(PeopleInfo_t))
int main(int argc, char *argv[])
{
Q_UNUSED(argc);
Q_UNUSED(argv);
bool isOK;
/************************************ [1] 将数据写入共享内存 ****************************************/
//1 创建共享内存操作对象
QSharedMemory *shm_write = new QSharedMemory("QtShmTest");
//2 创建共享内存
isOK = shm_write->create(SHM_SIZE, QSharedMemory::ReadWrite);
if (!isOK) {
qDebug()<<"create shm failed.";
return -1;
}
//准备数据
PeopleInfo_t people = {71, "zhangsan"};
//3 写入数据
shm_write->lock();//上锁
char *shm_addr = (char *)shm_write->data();//获取共享内存映射首地址
memcpy(shm_addr, &people, qMin(SHM_SIZE, sizeof(people)));//写入数据, 这里注意写入的数据长度不能超过共享内存的大小
shm_write->unlock();//解锁
//4 释放共享内存
//shm_write->detach(); //因为后面要测试读取,这里放在最后释放
/************************************ [2] 从共享内存读物数据 ****************************************/
//1 创建共享内存操作对象
QSharedMemory *shm_read = new QSharedMemory("QtShmTest");
//2 关联到指定的共享内存
shm_read->attach(QSharedMemory::ReadOnly);//只读
//3 读取数据
PeopleInfo_t peopleInfo = {0, ""};
shm_read->lock();//加锁
memcpy(&peopleInfo, shm_read->constData(), qMin(SHM_SIZE, sizeof(PeopleInfo_t)));
shm_read->unlock();//解锁
//4 释放资源
shm_read->detach();
qDebug()<<"age:"<<peopleInfo.age<<" name:"<<peopleInfo.name;
qDebug()<<"QtShm Test Finish. 2020.10.01 ";
shm_write->detach();
return 0;
}
四、效果
五、总结
5.1 注意事项
读写共享内存注意不要超过共享内存大小,注意加锁和解锁防止出现死锁情况,共享内存数据结构需要注意内存对齐,不然数据会发生偏移。
加锁解锁操作会降低操作共享内存的效率,但不加锁就容易导致几个程序同时修改共享内存从而发生数据丢失(相互覆盖)
所以对共享内存写入数据有必要加锁,对于读取共享内存数据,看具体需求(实时性,数据容错性,数据完整性),一般都会加锁。
5.2 重要步骤
1. 创建共享内存操作对象
QSharedMemory(const QString &key, QObject *parent = Q_NULLPTR);
2. 创建共享内存
bool create(int size, AccessMode mode = ReadWrite);
3. 共享内存关联--非创建者就需要关联,创建共享内存的不用该步骤
bool isAttached() const;//判断是否已经关联
bool attach(AccessMode mode = ReadWrite);//关联并指定读写方式
4. 共享内存数据操作,共享内存首地址
void *data();
const void* constData() const;
const void *data() const;
5 释放--取消关联
bool detach();
如果没有程序关联该共享内存,该共享内存才会真正被释放、被系统回收。