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



  • @CrazyDave

    I should note that pqsmCnfgMem->pcCnfgMem is from QSharedMemory->data()


  • Lifetime Qt Champion

    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' Allocated

    States 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' Allocated

    What 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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.