本例子利用虚拟内存实现不同进程或线程内的数据共享,不同进程中请勿使用信号槽update。
QSharedMemoryOper.h
#ifndef QSHAREDMEMORYOPER_H
#define QSHAREDMEMORYOPER_H
#include <QObject>
#include <QSharedMemory>
const static int nMemorySize = 1024 * 1024;
class QSharedMemoryOper : public QObject
{
Q_OBJECT
public:
QSharedMemoryOper(QObject *parent = nullptr);
~QSharedMemoryOper();
private:
QSharedMemory m_shareMemory;
public:
void SetKey(const QString &key);
int ReadData(char *pBuffer, int nMaxLen); //返回实际长度
int WriteData(char *pBuffer, int nLen, int nWritePos = -1); //写入全部数据
signals:
void update(); //数据更新
};
#endif // QSHAREDMEMORYOPER_H
QSharedMemoryOper.cpp
#include "qsharedmemoryoper.h"
static QMap<QString, QList<QSharedMemoryOper *>> sharedMemoryOperMap;
#pragma pack(push, 1) //按字节对齐begin
struct QSharedMemoryInfo
{
int nFlashLen; //代表有效数据大小
char pFlashData[1]; //代表数据
};
#pragma pack(pop) //按字节对齐end
QSharedMemoryOper::QSharedMemoryOper(QObject *parent)
: QObject(parent)
{}
QSharedMemoryOper::~QSharedMemoryOper()
{
QList<QSharedMemoryOper *> qList = sharedMemoryOperMap.value(m_shareMemory.key());
qList.removeOne(this);
sharedMemoryOperMap.insert(m_shareMemory.key(), qList);
m_shareMemory.detach();
}
void QSharedMemoryOper::SetKey(const QString &key)
{
if (key != "") {
m_shareMemory.setKey(key);
if (!m_shareMemory.create(nMemorySize + sizeof(int)))
m_shareMemory.attach();
QList<QSharedMemoryOper *> qList = sharedMemoryOperMap.value(key);
qList.append(this);
sharedMemoryOperMap.insert(key, qList);
}
}
int QSharedMemoryOper::ReadData(char *pBuffer, int nMaxLen)
{
if (m_shareMemory.isAttached()) {
m_shareMemory.lock();
QSharedMemoryInfo *pSharedMemoryInfo = (QSharedMemoryInfo *) m_shareMemory.data();
int nLen = nMaxLen >= pSharedMemoryInfo->nFlashLen ? pSharedMemoryInfo->nFlashLen : nMaxLen;
memcpy(pBuffer, pSharedMemoryInfo->pFlashData, nLen);
m_shareMemory.unlock();
return nLen;
}
return -1;
}
int QSharedMemoryOper::WriteData(char *pBuffer, int nLen, int nWritePos)
{
if (m_shareMemory.isAttached()
&& (nLen < nMemorySize - sizeof(int) || (nWritePos == -1 && nWritePos + nLen < nMemorySize - sizeof(int)))) {
m_shareMemory.lock();
QSharedMemoryInfo *pSharedMemoryInfo = (QSharedMemoryInfo *) m_shareMemory.data();
int nFlashLen = pSharedMemoryInfo->nFlashLen;
if (nWritePos == -1) {
pSharedMemoryInfo->nFlashLen = nLen;
nFlashLen = nLen;
memcpy(pSharedMemoryInfo->pFlashData, pBuffer, nLen);
} else {
memcpy(pSharedMemoryInfo->pFlashData + nWritePos, pBuffer, nLen);
return pSharedMemoryInfo->nFlashLen;
}
m_shareMemory.unlock();
QList<QSharedMemoryOper *> qList = sharedMemoryOperMap.value(m_shareMemory.key());
for (int i = 0; i < qList.length(); i++) {
if (qList.at(i) != this)
emit qList.at(i)->update();
}
return nFlashLen;
}
return -1;
}