Observe changes in QSharedMemory

1.1k views Asked by At

I have a QSharedMemory to prevent that two processes of my application are running at the same time. Process A sets the QSharedMemory to "locked" when started. Now my process B sets a value like "please come back to foreground".

Is there an easy way for process A to observe changes in the QSharedMemory, i.e. avoids implementing a stupid pulling timer?

3

There are 3 answers

0
jonspaceharper On

Here we are: QSystemSemaphore

Like its lighter counterpart QSemaphore, a QSystemSemaphore can be accessed from multiple threads. Unlike QSemaphore, a QSystemSemaphore can also be accessed from multiple processes.

Like QSharedMemory, QSystemSemaphore uses a key-based access method.

0
Kuba hasn't forgotten Monica On

Instead of using shared memory, the process could open a QLocalSocket to a named local server, and when it fails, open a QLocalServer. All subsequent processes will success to open the socket to the server, and can communicate with it. That's probably the simplest, most portable way of accomplishing the job.

You can also use QtSingleApplication, iff it has been ported to Qt 5.

0
Felix On

To answere your question: No, QSharedMemory does not have such a feature.

If you just want to have a "single instance" application, you can use https://github.com/Skycoder42/QSingleInstance.

It makes shure you have only 1 instance of you application at a time, can automatically bring the active window to the front and allows you to pass parameters from the new process to the running one.

Simple example:

#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include <qsingleinstance.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QSingleInstance instance;

    MainWindow *w = NULL;

    instance.setStartupFunction([&]() -> int {
        w = new MainWindow(NULL);
        instance.setNotifyWindow(w);
        w->show();
        return 0;
    });

    QObject::connect(qApp, &QApplication::aboutToQuit, [&](){
        delete w;
    });

    QObject::connect(&instance, &QSingleInstance::instanceMessage, [&](QStringList args){
        QMessageBox::information(w, "Message", args.join('\n'));
    });

    return instance.singleExec();
}

This will show the mainwindow, just like you woudl expect. If the application is run a second time, the currently running mainwindow will be raised to the foreground and a messagebox with the arguments will be shown.

Note: This example uses the QWidgets, but the QSingleInstance can be used with a gui or core application, too.