QSystemSemaphore
. It works like this:QSystemSemaphore
class, it creates a global (system) semaphoreacquire
, reduce the semaphore count by onerelease
, increment the semaphore count by oneacquire
, then until we call release
no one else can capture the semaphore. Hurray, the solution is found! The following code of the single-instance application immediately appears:release
(for example, the program has crumbled), the system will still return all units captured from it to the semaphore. But there is a problem. If the user starts the second instance of the application - how will he know about it? The call to the acquire
blocking method and until the semaphore is released the application will “hang”, and the user is at a loss for something to wait.QMutex
besides calling lock
to capture a mutex, has a call and try_lock
for a non-blocking capture attempt. There should be something similar in the system semaphore. But - alas - it is not. I have been googling long and unsuccessfully - the forums are full of similar topics and not a single working solution. Problem? Problem. Interesting? Quite. I undertook to solve it.QSystemSemaphore
obviously nothing will be resolved. What else is in Qt from global? Still have QSharedMemory
. Memory shared between different applications. It works like this:QSharedMemory
classattach
to connect to already created memorycreate
to create shared memorydetach
and detachment from shared memoryattach
was successful, then the application is already running. If not, the application is started for the first time, we call create
and, thus, we secure our superiority in the issue of ownership of shared memory (i.e., all other attach
will already be successful). There are actually two problems here.create
. One will create a memory, the other will fail. Not good, but, in general, tolerated. You can get around.QSharedMemory
Linux implementation QSharedMemory
designed so that if QSharedMemory
is not caused to memory, it is not destroyed. Simply put, if a process joins shared memory and then crashes, the memory will remain created. And the next attach
call will succeed. Those. the abnormal termination of a single instance of the application will result in no more instances of the application being created. Hmm.QSystemSemaphore
and QSharedMemory
, each of which partially implements the necessary functionality, but does not completely solve the final task. Maybe it will be possible to combine these two "underclass" harmoniously?QSystemSemaphore
solves the first problem QSharedMemory
, the problem of racing. Code: QSystemSemaphore sema("<Unique name1>", 1); bool isRunning; sema.acquire(); QSharedMemory shmem("<Unique name2>"); if (shmem.attach()) { isRunning = true; } else { shmem.create(1); isRunning = false; } sema.release();
QSystemSemaphore sema("<Unique name1>", 1); bool isRunning; sema.acquire(); { QSharedMemory shmem("<Unique name2>"); shmem.attach(); } QSharedMemory shmem("<Unique name2>"); if (shmem.attach()) { isRunning = true; } else { shmem.create(1); isRunning = false; } sema.release();
QSharedMemory
class QSharedMemory
be kept until the end of the application. And then everything works exactly as needed.Source: https://habr.com/ru/post/173281/
All Articles