Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

semaphore reading qstring example error



  • Hello guys,
    i am trying to use the semaphores shared memory to read a QString value. I am attaching my code. I can block the memory and detect it being blocked but can not read the value from the shared memory.

    thanks in advance for assistance

    #include "mainwindow.h"
    #include <QApplication>
    #include <QSystemSemaphore>
    #include <QSharedMemory>
    #include <QMessageBox>
    #include <QString>
    
    #include <QBuffer>
    #include <QtGlobal>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QSystemSemaphore semaphore("<uniq id>", 1);  // create semaphore
        semaphore.acquire(); // Raise the semaphore, barring other instances to work with shared memory
    
    #ifndef Q_OS_WIN32
        // in linux / unix shared memory is not freed when the application terminates abnormally,
        // so you need to get rid of the garbage
        QSharedMemory nix_fix_shared_memory("<uniq id 2>");
        if(nix_fix_shared_memory.attach()){
            nix_fix_shared_memory.detach();
        }
    #endif
    
        QSharedMemory sharedMemory("<uniq id 2>");  // Create a copy of the shared memory
        bool is_running;            // variable to test the already running application
    
        QBuffer buffer;
        int x=0; QString ux;
        QDataStream in(&buffer);
    
        if (sharedMemory.attach()){ // We are trying to attach a copy of the shared memory
                                    // To an existing segment
            is_running = true;      // If successful, it determines that there is already a running instance
            sharedMemory.lock();
            buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
            buffer.open(QBuffer::ReadOnly);
            char *from = (char*)sharedMemory.data();
            memcpy (from, &ux, sharedMemory.size());
            //in >> ux;
            sharedMemory.unlock();
    
        }else{
            buffer.open(QBuffer::ReadWrite);
            QDataStream out(&buffer);
            sharedMemory.create(2); // Otherwise allocate 1 byte of memory
            out << QString("Y");
            sharedMemory.lock();
            char *to = (char*)sharedMemory.data();
            const char *from = buffer.data().data();
            int size=buffer.size();
            memcpy(to, from, qMin(sharedMemory.size(), size));
            sharedMemory.unlock();
    
            //out << (int)1;
            is_running = false;     // And determines that another instance is not running
        }
        semaphore.release();
    
        // If you already run one instance of the application, then we inform the user about it
        // and complete the current instance of the application
        if(is_running){
            QMessageBox msgBox;
            QString u = QString::number(x);
            msgBox.setIcon(QMessageBox::Warning);
            msgBox.setText("The application is already running.\n"
                           "value " + ux);
            msgBox.exec();
            return 1;
        }
    
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    

  • Moderators

    You are aware of QtSingleApplication, right? https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication

    And a string can be (simpler) saved to and read from a file (for example using QSettings).

    Which is another way of saying "I've never used QSystemSemaphore or QSharedMemory and don't know how to help you" ;-)



  • @sierdzio I need to exchange data between different applications


  • Lifetime Qt Champion

    Hi,

    What exactly are you trying to exchange between the two applications ?



  • i am trying to exchange a string. Actually i wanted to create a slot in app B that responds to a signal from App A and tried to do it with semaphore but i think this is not the correct approach. I think doing it with dBus may be better or using local network is also another approach.


  • Moderators

    @SherifOmran said in semaphore reading qstring example error:

    I think doing it with dBus may be better or using local network is also another approach.

    There is also the (quite new) QtRemoteObjects module.



  • @sierdzio : do you know if there is an example to do it?
    thank you


  • Moderators

    have not used it myself yet, so all I can do is point to the docs. It was developed by a company doing industrial projects and contributed to Qt, I expect it to work quite well for sending data between apps.


  • Lifetime Qt Champion

    Hi
    Just as a note this sample does work
    https://doc.qt.io/qt-5/qtcore-ipc-sharedmemory-example.html



  • @SherifOmran

    I can block the memory and detect it being blocked but can not read the value from the shared memory.

    If you want to do it your way, and if I read your code right:

    QString ux;
            char *from = (char*)sharedMemory.data();
            memcpy (from, &ux, sharedMemory.size());
    

    This writes to the shared memory area, named from, from the QString, which is empty.

    If I didn't know better, I'd wonder whether you simply have your arguments to memcpy() the wrong way round; don't you intend:

            memcpy (&ux, from, sharedMemory.size());
    

    This is in the code which attaches to a segment already created by your other, creation route, so I presume it's supposed to be reading into the QString what the other route left there. [Meanwhile I imagine you're not supposed to write directly into a QString like this, so it may well go wrong in that sense, but that's a different matter...]


Log in to reply