Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to share data between processes using QSharedMemory?
Forum Updated to NodeBB v4.3 + New Features

How to share data between processes using QSharedMemory?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 1.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Roberrt
    wrote on last edited by Roberrt
    #6

    I got it working now, something that i should change or take note?
    process1

    struct Data {
        QMap<int, QString> map;
    };
    
    filemap1::filemap1(QWidget* parent)
        : QMainWindow(parent)
        , ui(new Ui::filemap1Class())
    {
        ui->setupUi(this);
    
        // Create an instance of QSharedMemory and attach it to a unique key
        sharedMemory.setKey("MyKey");
    
        Data data;
        data.map[1] = "Hello";
        data.map[2] = "World";
    
        QByteArray serializedData;
        QDataStream stream(&serializedData, QIODevice::WriteOnly);
        stream << data.map;
    
        if (!sharedMemory.create(serializedData.size())) 
        {
            if (!sharedMemory.attach()) {
                qWarning() << "Unable to attach to shared memory: " << sharedMemory.errorString();;
                return;
            }
        }
    
        sharedMemory.lock();
        char* sharedMemoryData = static_cast<char*>(sharedMemory.data());
        std::memcpy(sharedMemoryData, serializedData.constData(), serializedData.size());
        sharedMemory.unlock();
    }
    

    process2

    struct Data {
        QMap<int, QString> map;
    };
    
    filemap2::filemap2(QWidget *parent) : QMainWindow(parent) , ui(new Ui::filemap2Class())
    {
        ui->setupUi(this);
    
        // Create an instance of QSharedMemory and attach it 
        // to the same key as process 1
        QSharedMemory sharedMemory("MyKey");
        if (!sharedMemory.attach()) {
            qWarning() << "Unable to attach to shared memory: " << sharedMemory.errorString();;
            return;
        }
    
        sharedMemory.lock();
        // Read the serialized data from shared memory
        char* sharedMemoryData = static_cast<char*>(sharedMemory.data());
        QByteArray serializedData(sharedMemoryData, sharedMemory.size());
    
        // Deserialize the object
        QDataStream stream(&serializedData, QIODevice::ReadOnly);
        Data data;
        stream >> data.map;
    
        sharedMemory.unlock();
    }
    

    How do i avoid the process getting stuck when trying to attach to a sharedMemory which is locked for too much time?

    For example, if process2 lock the sharedMemory and crash, when process1 try to read it, it will stuck, as it wait forever to the memory be unlocked.

    JonBJ 1 Reply Last reply
    0
    • R Roberrt

      I got it working now, something that i should change or take note?
      process1

      struct Data {
          QMap<int, QString> map;
      };
      
      filemap1::filemap1(QWidget* parent)
          : QMainWindow(parent)
          , ui(new Ui::filemap1Class())
      {
          ui->setupUi(this);
      
          // Create an instance of QSharedMemory and attach it to a unique key
          sharedMemory.setKey("MyKey");
      
          Data data;
          data.map[1] = "Hello";
          data.map[2] = "World";
      
          QByteArray serializedData;
          QDataStream stream(&serializedData, QIODevice::WriteOnly);
          stream << data.map;
      
          if (!sharedMemory.create(serializedData.size())) 
          {
              if (!sharedMemory.attach()) {
                  qWarning() << "Unable to attach to shared memory: " << sharedMemory.errorString();;
                  return;
              }
          }
      
          sharedMemory.lock();
          char* sharedMemoryData = static_cast<char*>(sharedMemory.data());
          std::memcpy(sharedMemoryData, serializedData.constData(), serializedData.size());
          sharedMemory.unlock();
      }
      

      process2

      struct Data {
          QMap<int, QString> map;
      };
      
      filemap2::filemap2(QWidget *parent) : QMainWindow(parent) , ui(new Ui::filemap2Class())
      {
          ui->setupUi(this);
      
          // Create an instance of QSharedMemory and attach it 
          // to the same key as process 1
          QSharedMemory sharedMemory("MyKey");
          if (!sharedMemory.attach()) {
              qWarning() << "Unable to attach to shared memory: " << sharedMemory.errorString();;
              return;
          }
      
          sharedMemory.lock();
          // Read the serialized data from shared memory
          char* sharedMemoryData = static_cast<char*>(sharedMemory.data());
          QByteArray serializedData(sharedMemoryData, sharedMemory.size());
      
          // Deserialize the object
          QDataStream stream(&serializedData, QIODevice::ReadOnly);
          Data data;
          stream >> data.map;
      
          sharedMemory.unlock();
      }
      

      How do i avoid the process getting stuck when trying to attach to a sharedMemory which is locked for too much time?

      For example, if process2 lock the sharedMemory and crash, when process1 try to read it, it will stuck, as it wait forever to the memory be unlocked.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #7

      @Roberrt
      I think the attach() is OK, you mean when the second process tries a lock().
      I think the answer is that Qt does not provide any kind of tryLock(), see https://bugreports.qt.io/browse/QTBUG-4073 and https://bugreports.qt.io/browse/QTBUG-2443.
      I don't know what happens of one side actually "crashes", OS-dependent behaviour as to whether it gets released.
      There may be other ways to share data with IPC which don't risk this QSharedMemory behaviour if that is important to you.

      R 1 Reply Last reply
      0
      • JonBJ JonB

        @Roberrt
        I think the attach() is OK, you mean when the second process tries a lock().
        I think the answer is that Qt does not provide any kind of tryLock(), see https://bugreports.qt.io/browse/QTBUG-4073 and https://bugreports.qt.io/browse/QTBUG-2443.
        I don't know what happens of one side actually "crashes", OS-dependent behaviour as to whether it gets released.
        There may be other ways to share data with IPC which don't risk this QSharedMemory behaviour if that is important to you.

        R Offline
        R Offline
        Roberrt
        wrote on last edited by
        #8

        @JonB How to keep the sharedMemory even after process1 exit?

        JonBJ 1 Reply Last reply
        0
        • R Roberrt

          @JonB How to keep the sharedMemory even after process1 exit?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #9

          @Roberrt
          Have you read the platform description in https://doc.qt.io/qt-6/qsharedmemory.html#details ?

          It also says

          QSharedMemory automatically destroys the shared memory segment when the last instance of QSharedMemory is detached from the segment, and no references to the segment remain.

          I think if process1 exits but process 2 has attached it persists. Until all processes have released it.

          R 1 Reply Last reply
          1
          • JonBJ JonB

            @Roberrt
            Have you read the platform description in https://doc.qt.io/qt-6/qsharedmemory.html#details ?

            It also says

            QSharedMemory automatically destroys the shared memory segment when the last instance of QSharedMemory is detached from the segment, and no references to the segment remain.

            I think if process1 exits but process 2 has attached it persists. Until all processes have released it.

            R Offline
            R Offline
            Roberrt
            wrote on last edited by
            #10

            @JonB I see, whats the best way to inform process2 that new data has been written to the QSharedMemory?

            JonBJ 1 Reply Last reply
            0
            • R Roberrt

              @JonB I see, whats the best way to inform process2 that new data has been written to the QSharedMemory?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #11

              @Roberrt
              You might have to have a semaphore for that. There isn't a "notification".
              Before you go any further you should read

              • https://forum.qt.io/topic/120197/qsharedmemory-update-signal
              • https://stackoverflow.com/questions/37121384/observe-changes-in-qsharedmemory

              and consider your alternatives, and what you are using the shared memory for.

              1 Reply Last reply
              0
              • Kent-DorfmanK Offline
                Kent-DorfmanK Offline
                Kent-Dorfman
                wrote on last edited by
                #12

                Another huge mistake people make when using shared memory is they think in terms of peer-to-peer, which is bad juju. You really have to manage shared memory as a master/slave relationship. ie, it is set-up/initialized by a controller and then some number of other processes can use it...and there is no implicit "notify of changes" mechanism. you have to poll for changes or implement some sort of cross-process signalling mechanism in addition to correct use of semaphores/mutexes.

                1 Reply Last reply
                1
                • R Offline
                  R Offline
                  Roberrt
                  wrote on last edited by
                  #13

                  Do i still need to call .lock into the QSharedMemory when i'm just reading it without modifying the data?

                  JonBJ Kent-DorfmanK 2 Replies Last reply
                  0
                  • R Roberrt

                    Do i still need to call .lock into the QSharedMemory when i'm just reading it without modifying the data?

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #14

                    @Roberrt
                    void *QSharedMemory::data()

                    Remember to lock the shared memory with lock() before reading from or writing to the shared memory

                    If you don't lock() for read and someone else has lock()ed and writes, I simply don't know/maybe not defined what you see in the read.

                    1 Reply Last reply
                    0
                    • R Roberrt

                      Do i still need to call .lock into the QSharedMemory when i'm just reading it without modifying the data?

                      Kent-DorfmanK Offline
                      Kent-DorfmanK Offline
                      Kent-Dorfman
                      wrote on last edited by Kent-Dorfman
                      #15

                      @Roberrt

                      Read characteristics are undefined if you don't guarantee exclusive access, or at least use data types that are guaranteed to be atomic. Generally the read of a native word sized int is atomic across architectures because the CPU microcode likes to deal with a whole word at a time, and preemption wont occur in the middle of a machine code instruction.

                      But it is safer to lock for reads as well.

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved