Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    [SOLVED] QSharedMemory checking

    General and Desktop
    3
    7
    6683
    Loading More Posts
    • 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
      willypuzzle last edited by

      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 Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        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 Reply Quote 0
        • W
          willypuzzle last edited by

          Different processes

          1 Reply Last reply Reply Quote 0
          • B
            bodzio131 last edited by

            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 Reply Quote 0
            • W
              willypuzzle last edited by

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

              1 Reply Last reply Reply Quote 0
              • B
                bodzio131 last edited by

                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 Reply Quote 0
                • W
                  willypuzzle last edited by

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

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post