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. [SOLVED] QSharedMemory checking
QtWS25 Last Chance

[SOLVED] QSharedMemory checking

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 7.2k 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.
  • W Offline
    W Offline
    willypuzzle
    wrote on last edited by
    #1

    I would know if a way to call some function exists when a content of QSharedMemory is updated.
    Now I have to check every second the content of a QShareMemory in order to know if it contains what I need.
    I would like know if a way to avoid this continue checking exists.
    But I saw QSharedMemory doesn't emit any signal (except destroyed() that it inherit from QObject).

    There is a way to do that?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Who access the QSharedMemory ? Different threads or different processes ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • W Offline
        W Offline
        willypuzzle
        wrote on last edited by
        #3

        Different processes

        1 Reply Last reply
        0
        • B Offline
          B Offline
          bodzio131
          wrote on last edited by
          #4

          I understand that you want to synchronize read/write without pooling. I would create separated thread and use QSystemSemaphore, or QSharedMemory lock/unlock methods, to wait for access and then I would signal other threads that shared data is ready.

          1 Reply Last reply
          0
          • W Offline
            W Offline
            willypuzzle
            wrote on last edited by
            #5

            Could you do a example? Please.
            This "checking" thread should do pooling ....

            1 Reply Last reply
            0
            • B Offline
              B Offline
              bodzio131
              wrote on last edited by
              #6

              Well, I hope you can do something with my messy example. I didn't consider waiting for threads termination, memory freeing and server separated thread for sending messages (in case client reads data too long time), just the main problem: waiting for shared memory without active pooling.

              You need to run two processes (the same executable), they will configure themselves. The first one sends message on button clicked event, and the second one waits, receives and shows text in QLabel. You can use QSharedMemory lock/unlock or QSystemSemaphore interchangeably, see comments in cpp. You need to use uic/moc and build ui by yourself, ther is only QLineEdit (whatToSend), QPushButton and QLabel (whatReceived).

              @
              //main.cpp
              #include "MainDialog.h"

              #include <QtWidgets\qapplication.h>

              int main( int _argc, char** _argv )
              {
              QApplication app( _argc, _argv );

              MainDialog dlg;
              dlg.show();

              return app.exec();
              }
              @

              @
              //MainDialog.h
              #pragma once

              #include "dialog.h"

              #include <QtWidgets\qdialog.h>
              #include <QtCore\qsharedmemory.h>
              #include <QtCore\qthread.h>
              #include <QtCore\qsystemsemaphore.h>

              class Client
              : public QThread
              {
              Q_OBJECT
              public:
              Client( QSharedMemory & _sharedMemory );
              void run();

              Q_SIGNALS:
              void textReady( QString );

              private:
              QSystemSemaphore m_semaphoreWriteDone;
              QSharedMemory & m_sharedMemory;
              };

              class MainDialog :
              public QDialog
              , public Ui::Dialog
              {
              Q_OBJECT
              public:
              MainDialog();
              ~MainDialog();

              public Q_SLOTS:
              void onTextReady( QString );
              void onSend();

              private:
              QSharedMemory m_sharedMemory;
              QSystemSemaphore m_semaphoreWriteDone;
              };
              @

              @
              //MainDialog.cpp
              #include "MainDialog.h"

              #include <QtCore\qtextstream.h>

              #include "MainDialog.moc"

              //you can comment semaphores and uncomment lock/unlock, result will be the same

              Client::Client( QSharedMemory & _sharedMemory )
              : m_semaphoreWriteDone( "SemaphoreWriteDone" ) //I assume that counter is already initialized by the server
              , m_sharedMemory( _sharedMemory )
              {
              start();
              }

              void
              Client::run()
              {
              while ( true )
              {
              //there is no active pooling, we just wait for semaphore
              m_semaphoreWriteDone.acquire();

              //m_sharedMemory.lock();
              char const * from = ( char const * )m_sharedMemory.data();

              QString text;
              QTextStream stream( &text );
              while ( from && *from )
              {
              stream << *from;
              ++from;
              }

              //m_sharedMemory.unlock();

              m_semaphoreWriteDone.release();

              Q_EMIT textReady( text );
              }
              }

              MainDialog::MainDialog(void)
              : m_sharedMemory( "MySharedMemory" )
              , m_semaphoreWriteDone( "SemaphoreWriteDone", 0 )
              {
              setupUi( this );

              bool result;
              if ( result = m_sharedMemory.create( 1024 ) )
              {
              //We've created memory, so we are first. This one will send messages.
              char to = (char)m_sharedMemory.data();
              memset( to, 0, m_sharedMemory.size() );

              connect( m_sendButton, SIGNAL( clicked() ), this, SLOT( onSend() ) );
              }
              else
              {
              //Shared memory already exists, so this is second process. This one will listen.
              result = m_sharedMemory.attach();
              Q_ASSERT( result );

              m_sendButton->setEnabled( false );

              Client * client = new Client( m_sharedMemory );
              connect( client, SIGNAL( textReady( QString ) ), this, SLOT( onTextReady( QString ) ) );
              }
              }

              MainDialog::~MainDialog(void)
              {
              //need to add waiting for thread termination
              }

              void
              MainDialog::onTextReady( QString _text )
              {
              m_receivedTextLabel->setText( _text );
              }

              void
              MainDialog::onSend()
              {
              //m_sharedMemory.lock();
              char to = (char)m_sharedMemory.data();

              QString text = m_whatToSend->text();
              QChar *data = text.data();
              while ( !data->isNull() )
              {
              memset( to, data->toLatin1(), 1 );
              ++data;
              ++to;
              }
              memset( to, 0, 1 ); //null terminator
              //m_sharedMemory.unlock();
              //m_sharedMemory.lock();

              //resume other process
              m_semaphoreWriteDone.release();

              //this one will block client again, however, it could take time for client to read data, so generally
              //we should send data also from separated thread if we don't want to block gui
              m_semaphoreWriteDone.acquire();
              }
              @

              1 Reply Last reply
              0
              • W Offline
                W Offline
                willypuzzle
                wrote on last edited by
                #7

                Thanks very much for the example and for the hints, I'll be working on it :)

                1 Reply Last reply
                0

                • Login

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