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