Qt-C++ - Урок 043. Qt Single Application - запускаємо лише один екземпляр програми

Дозвіл запуску лише одного екземпляра програми може бути необхідним для обмеження проблем з витоком пам'яті, або для усунення можливих проблем з конкуренцією двох екземплярів програми за одні ресурси, файли, база даних SQLite і т.д. Або якщо програма в принципі передбачає лише один екземпляр, який використовується користувачем.

Для вирішення цієї задачі можна використовувати два наступні способи:

  • За допомогоюQLockFile - коли створюється тимчасовий файл, який знищується при закритті програми. При цьому при запуску другого екземпляра програми відбувається перевірка на існування даного файлу і якщо файл вже створений одним відкритим екземпляром програми, другий екземпляр автоматично закривається;
  • З використаннямQSystemSemaphore іQSharedMemory - в даному випадку створюється сегмент пам'яті, що розділяється, і робиться спроба приєднати його до існуючого сегменту за унікальним ідентифікатором. Якщо спроба приєднання пройшла успішно, один екземпляр програми вже створено. Відповідно, повідомляємо про це користувачеві та закриваємо програму. Якщо спроба приєднання пройшла безуспішно, то створюємо виділяємо сегмент пам'яті для програми і запускаємо перший екземпляр.

Весь подальший програмний код не виходитиме за межі main.cpp.

Single application з використанням QLockFile

У наведеному нижче коді в папці для тимчасових файлів під час запуску програми створюєтьсяLock File, у разі невдалої спроби створенняLock File, програма вважає, що вже відкрито один екземпляр програми, повідомляє про це користувачеві та закривається.

Примітка. Замініть ваш ідентифікатор.

Single application з використаннямQSystemSemaphore та QSharedMemory

У першому варіанті дано просте та зручне рішення задачі з обмеження кількості запущених екземплярівQt програми. Але рішення наQLockFile має і недоліки в тому плані, що можуть бути проблеми з дозволами для користувача. А також, якщо ви хочете обмежити, запуск програми одним екземпляром на весь комп'ютер, не розрізняючи те, скільки сесій користувача може бути запущено на ньому, то використанняQLockFile також не забезпечить цю можливість.

QSharedMemory навпаки є розділяється всім користувачів одночасно, що працюють за комп'ютером. Тому якщо один із користувачів запустив Вашу програму, то другий вже не зможе її запустити.

Але в даному варіанті необхідно не забувати про відмінності в роботі з пам'яттю, що розділяється під різними платформами. У випадку зWindows, пам'ять, що розділяється, буде звільнена як при штатному завершенні програми, так і при аварійному завершенні. У випадку зLinux/Unix при аварійному при аварійному завершенні пам'ять звільнена не буде.

У наведеному нижче коді семафор використовується для вирішення проблеми гонок у випадку з одночасним запуском кількох примірників однієї програми. Семафор створюється зі лічильником, максимальне число якого дорівнює 1. При піднятті семафору, всі інші екземпляри програми вже не мають доступу до пам'яті, що розділяється, і відповідно один екземпляр повністю володіє ресурсами. Цей екземпляр перевіряє наявність запущеного іншого екземпляра програми за наявністю сегмента пам'яті, що розділяється, з ідентифікатором, відповідним даному додатку. Екземпляр успішно запускається і створює сегмент пам'яті, що розділяється у разі, якщо не знайшов інформації про інший екземпляр програми.Після цього семафор опускається, даючи можливість іншим екземплярам програми спробувати запуститися.

Примітка. Замініть і ваші ідентифікатор.