Solved QSharedMemory - Addressing shared memory problems
-
I haven’t used shared memory before. I have two applications that access the same shared memory though QSharedMemory. At startup each application accesses the same memory map table in mySql. Each record has is unique in names and calculated offset. Both programs load and execute, but when I write something to the shared memory in one application it is not reflected in the other. The logical address I get from QsharedMemory->data() is different in each application, and from what I have read this is correct. Here are some snippets of my code which assigns addressing (both programs use same source code for this).
QSqlQuery *QMemAsgn::GetMemMapQuery(void) { QString strQuery; QSqlQuery *psqlqTemp; uint uiSize; strQuery = QString(cDbPrcCfgTbMem_mQryMemTypeUniqueRec1)\ .arg(strFields[cMemMapMain])\ .arg(strFields[cMemMapSubp])\ .arg(strFields[cMemMapLoop])\ .arg(strFields[cMemMapPnt1])\ .arg(strFields[cMemMapPnt2])\ .arg(strFields[cMemMapPnt3])\ .arg(strFields[cMemMapPnt4])\ .arg(strFields[cMemMapPnt5])\ .arg(strFields[cMemMapPnt6])\ ; psqlqTemp = new QSqlQuery(strQuery, (QSqlDatabase) pdbmMain->dbPrcsCnfg); uiSize = psqlqTemp->size(); if (uiSize == 1) return psqlqTemp; else return NULL; // return new QSqlQuery(strQuery, (QSqlDatabase) pdbmMain->dbPrcsCnfg); } bool QMemAsgn::AssignMaskMemory(cMaskType **pcmtCurrent, cMaskType uiBitMask) { QSqlQuery *psqlqTemp; ulong ulOffset; psqlqTemp = GetMemMapQuery(); if (psqlqTemp->first()) { ulOffset = psqlqTemp->value(cDbPrcCfgTbMemFldMemOffset).toULongLong(); *pcmtCurrent = (cMaskType *) (pqsmCnfgMem->pcCnfgMem + ulOffset); **pcmtCurrent = (cMaskType) (psqlqTemp->value(cDbPrcCfgTbMemFldLastValue).toUInt() & uiBitMask); return true; } bool QMemAsgn::AssignNamePointer(char **pcCurrent, ulong ulAddress) { QSqlQuery *psqlqTemp; ulong ulOffset; psqlqTemp = GetMemMapQuery(); if (psqlqTemp->first()) { ulOffset = psqlqTemp->value(cDbPrcCfgTbMemFldMemOffset).toULongLong(); *pcCurrent = (char *) (pqsmCnfgMem->pcCnfgMem + ulOffset); **pcCurrent = (ulong) ulAddress; return true; } else return false; }
And here some snippets using the pointers to assign real values (not the same source).
Application one:void QLust::SetFieldParameters(void) { if (bLoopModel) // Linear { if (*pqlParent->lcPCL.mtcfCV.mtbAltVal.pbValue) *pqlParent->lcPCL.mtcfCV.mtfAltVal.pfValue = fCVtm0; else *pqlParent->lcPCL.mtcfCV.mtfValue.pfValue = fCVtm0; } else // Velocity { if (*pqlParent->lcPCL.mtcfCV.mtbAltVal.pbValue) *pqlParent->lcPCL.mtcfCV.mtfAltVal.pfValue = fCVtm0; else *pqlParent->lcPCL.mtcfCV.mtfValue.pfValue = fCVtm0; } return; }
Application two:
void QPlant::TrnsfrFromShrdMem(void) { uint uiIndex; for (uiIndex = cVariableDepth - 1 ; uiIndex > 0 ; uiIndex--) fCV[uiIndex] = fCV[uiIndex-1]; fCV[0] = (cFloatType) *mtcfCV.mtfValue.pfValue; return; }
I have checked and the same pointers in each application have the same offset. What am I doing wrong? Any ideas or suggestions?
Thanks
Dave -
I should note that pqsmCnfgMem->pcCnfgMem is from QSharedMemory->data()
-
Hi,
Are you properly locking the QSharedMemory object before doing your accesses ?
-
@SGaist Yes I am using the lock. I created two small test programs and they are communicating. However with the two small programs the address returned by QSharedMemory->data() is the same, where on my two large programs they are not. I am using the same key for both programs, "size()" returns the same size. I can allocated 1mb on the smaller programs and index it all the way to the end.
-
@CrazyDave
I found the source of the problem. QSharedMemory in the second program is not attaching to the allocated memory of the first program. The common code for shared memory:#include "mainwindow.h" #include "sharedmemory.h" extern QPcDebug *pdbg; QShrMem::QShrMem(void) { QString strKey = QString(cMemProcessConfig); pqsmMem = new QSharedMemory((const QString) strKey,this); bMemAllocated = false; return; } QShrMem::~QShrMem() { DetachSharedMemory(); } void QShrMem::SetupSharedMemory(ulong ulDesiredSize) { ulong ulBlocks; ulBlocks = (ulDesiredSize/cMemBlockSize) + 2L; ulMemSize = ulBlocks * cMemBlockSize; if (!pqsmMem->attach(QSharedMemory::ReadWrite)) { #ifdef DEBUG_OUT if (pqsmMem->error()) pdbg->DebugOut("SetupSharedMemory",QString("%1 - Key:'%2' - attach ERROR - '%3'")\ .arg(PROGRAM)\ .arg(pqsmMem->key())\ .arg(pqsmMem->errorString())\ ); #endif pqsmMem->create(ulMemSize,QSharedMemory::ReadWrite); #ifdef DEBUG_OUT pdbg->DebugOut("SetupSharedMemory",QString("%1 - Key:'%2' - Size:'0x%3'b - Pntr:'0x%4' Allocated")\ .arg(PROGRAM)\ .arg(pqsmMem->key())\ .arg((ulong) pqsmMem->size(), 6, 16, QChar('0'))\ .arg((ulong) pqsmMem->data(), 10, 16, QChar('0'))\ ); #endif } #ifdef DEBUG_OUT else pdbg->DebugOut("SetupSharedMemory",QString("%1 - Key:'%2' - Size:'0x%3'b - Pntr:'0x%4' Attached")\ .arg(PROGRAM)\ .arg(pqsmMem->key())\ .arg((ulong) pqsmMem->size(), 6, 16, QChar('0'))\ .arg((ulong) pqsmMem->data(), 10, 16, QChar('0'))\ ); #endif if (!pqsmMem->error()) { pcCnfgMem = (char *) pqsmMem->data(); bMemAllocated = true; } #ifdef DEBUG_OUT else pdbg->DebugOut("SetupSharedMemory",QString("%1 - Key:'%2' - Size:'0x%3' - shared memory ERROR - '%3'")\ .arg(PROGRAM)\ .arg(cMemProcessConfig)\ .arg((ulong) pqsmMem->size(), 6, 16, QChar('0'))\ .arg(pqsmMem->errorString())\ ); #endif return; } void QShrMem::DetachSharedMemory(void) { // Free shared memory if (bMemAllocated) { pqsmMem->detach(); bMemAllocated = false; } return; }
The outputs in the debug files:
Control program opening first:
18-03-25|18:51:14:613|-Location: OpenDb; Data: okay - opened process_config with QMYSQL
18-03-25|18:51:14:636|-Location: SetupSharedMemory; Data: Control - Key:'processconfig' - attach ERROR - 'QSharedMemory::handle:: UNIX key file doesn't exist'
18-03-25|18:51:14:636|-Location: SetupSharedMemory; Data: Control - Key:'processconfig' - Size:'0x070000'b - Pntr:'0x7fe7d07e7000' AllocatedStates that key does not exist, that's good allocates memory
Communications program opening second:
18-03-25|18:51:47:849|-Location: OpenDb; Data: okay - opened process_config with QMYSQL
18-03-25|18:51:47:904|-Location: SetupSharedMemory; Data: Comm - Key:'processconfig' - attach ERROR - 'QSharedMemory::attach (shmget): doesn't exist'
18-03-25|18:51:47:904|-Location: SetupSharedMemory; Data: Comm - Key:'processconfig' - Size:'0x070000'b - Pntr:'0x7f640c5ae000' AllocatedWhat is "'QSharedMemory::attach (shmget): doesn't exist", help!
-
SOLVED
I had a different version of QT on each, version 5.7 and 5.10. Once I had them set the same, either version, the second program attached properly.
-
One last comment, the logical addresses were different in the larger programs, but everything works with the offsets.