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?
QtWS25 Last Chance

How to share data between processes using QSharedMemory?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 4 Posters 1.6k Views
  • 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.
  • Christian EhrlicherC Christian Ehrlicher

    You can not share objects snce most of them have pointers to other memory in their private implementations - only plain data, or serialized objects

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

    @Christian-Ehrlicher how to serialize the object? qt has implementation for this task?

    Christian EhrlicherC JonBJ 2 Replies Last reply
    0
    • R Roberrt

      @Christian-Ehrlicher how to serialize the object? qt has implementation for this task?

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #4

      @Roberrt said in How to share data between processes using QSharedMemory?:

      qt has implementation for this task?

      You can use QDataStream for it.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • R Roberrt

        @Christian-Ehrlicher how to serialize the object? qt has implementation for this task?

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

        @Roberrt
        And Serializing Qt Data Types lists which Qt classes come with support. Note that this does not include any kind of QObject!

        1 Reply Last reply
        1
        • 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