Evgenii Legotckoi
Evgenii LegotckoiҚаң. 28, 2016, 11:11 Т.Ж.

Qt/C++ - сабақ 043. Qt Single Application - тек бір қолданба данасын іске қосыңыз

Тек бір қолданба данасын іске қосуға рұқсат беру жадтың ағып кетуіне қатысты мәселелерді шектеу немесе бірдей ресурстар, файлдар, SQLite дерекқоры және т.б. үшін бәсекелес екі қолданба даналарымен ықтимал ақауларды жою үшін қажет болуы мүмкін. Немесе қолданба, негізінен, пайдаланушы пайдаланатын бір ғана дананы қабылдайтын болса.

Бұл мәселені шешу үшін келесі екі әдісті қолдануға болады:

  • QLockFile пайдалану - қолданба жабылған кезде жойылатын уақытша файл жасалғанда. Бұл ретте қосымшаның екінші данасы іске қосылған кезде осы файлдың бар-жоғына тексеру жүргізіледі және егер файл қолданбаның бір ашық данасы арқылы жасалған болса, онда екінші данасы автоматты түрде жабылады;
  • QSystemSemaphore және QSharedMemory пайдалану - бұл жағдайда ортақ жад сегменті жасалады және оны бірегей идентификатор арқылы бар сегментке қосу әрекеті жасалады. Тіркеме әрекеті сәтті болса, бір қолданба данасы әлдеқашан жасалған. Тиісінше, біз бұл туралы пайдаланушыға хабарлаймыз және қолданбаны жабамыз. Тіркеу әрекеті сәтсіз болса, біз қолданба үшін жад сегментін жасаймыз және бірінші дананы іске қосамыз.

Бағдарламаның барлық келесі коды main.cpp шегінен шықпайды.

QLockFile қолданатын жалғыз қолданба

Төмендегі кодта қолданба іске қосылған кезде уақытша файлдар қалтасында Lock File жасалады; Lock File құру әрекеті сәтсіз болған жағдайда, бағдарлама қолданбаның бір данасы деп есептейді. әлдеқашан ашық, ол туралы пайдаланушыға хабарлайды және жабылады.

Ескерту. Ауыстыру жеке куәлігіңізге.

#include "widget.h"
#include <QApplication>
#include <QLockFile>
#include <QDir>
#include <QMessageBox>

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

    QLockFile lockFile(QDir::temp().absoluteFilePath("lurity.lock"));

    /* Пытаемся закрыть Lock File, если попытка безуспешна в течение 100 миллисекунд,
     * значит уже существует Lock File созданный другим процессом.
     * Следовательно, выбрасываем предупреждение и закрываем программу
     * */
    if (!lockFile.tryLock(100))
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText("Приложение уже запущено.\n"
                       "Разрешено запускать только один экземпляр приложения.");
        msgBox.exec();
        return 1;
    }

    Widget w;
    w.show();

    return a.exec();
}

QSystemSemaphore және QSharedMemory көмегімен жалғыз қолданба

Бірінші нұсқа Qt қолданбасының іске қосылған даналарының санын шектеу мәселесінің қарапайым және ыңғайлы шешімін береді. Бірақ QLockFile шешімінің кемшіліктері де бар, себебі пайдаланушы үшін рұқсат мәселелері болуы мүмкін. Сондай-ақ, бағдарламаны бүкіл компьютерде бір данада іске қосуды шектегіңіз келсе, онда қанша пайдаланушы сеансы іске қосылатынына қарамастан, QLockFile пайдалану да бұл мүмкіндікті қамтамасыз етпейді.

QSharedMemory , керісінше, компьютерде бір уақытта жұмыс істейтін барлық пайдаланушыларға ортақ. Сондықтан, егер пайдаланушылардың бірі сіздің бағдарламаңызды іске қосса, екіншісі оны енді іске қоса алмайды.

Бірақ бұл жағдайда әртүрлі платформаларда ортақ жадпен жұмыс істеудегі айырмашылықтар туралы ұмытпау керек. Windows, жағдайында ортақ жад бағдарламаның қалыпты аяқталуы кезінде де, әдеттен тыс аяқталғанда да босатылады. Linux/Unix жағдайында, бұзылған кезде жад босатылмайды.

Төмендегі кодта бір қолданбаның бірнеше даналары бір уақытта іске қосылған кезде жарыс шартын шешу үшін семафор пайдаланылады. Семафор есептегішпен жасалады, оның ең көп саны 1. Семафор көтерілген кезде қолданбаның барлық басқа даналары ортақ жадқа енді қатынаса алмайды және сәйкесінше бір данасы ресурстарға толық иелік етеді. Бұл дана қолданбаға сәйкес идентификаторы бар ортақ жад сегментінің болуы арқылы іске қосылған қолданбаның басқа данасын тексереді. Дана сәтті басталады және басқа қолданба данасы туралы ақпаратты таппаған жағдайда ортақ жад сегментін жасайды. Содан кейін семафор жойылып, қолданбаның басқа даналарына бастауға әрекет жасауға мүмкіндік береді.

Ескерту. Ауыстыру Және жеке куәлігіңізге.

#include "mainwindow.h"
#include <QApplication>
#include <QSystemSemaphore>
#include <QSharedMemory>
#include <QMessageBox>

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

    QSystemSemaphore semaphore("<uniq id>", 1);  // создаём семафор
    semaphore.acquire(); // Поднимаем семафор, запрещая другим экземплярам работать с разделяемой памятью

#ifndef Q_OS_WIN32
    // в linux/unix разделяемая память не освобождается при аварийном завершении приложения,
    // поэтому необходимо избавиться от данного мусора
    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>");  // Создаём экземпляр разделяемой памяти
    bool is_running;            // переменную для проверки ууже запущенного приложения
    if (sharedMemory.attach())
    {                           // пытаемся присоединить экземпляр разделяемой памяти
                                // к уже существующему сегменту
        is_running = true;      // Если успешно, то определяем, что уже есть запущенный экземпляр
    } 
    else
    {
        sharedMemory.create(1); // В противном случае выделяем 1 байт памяти
        is_running = false;     // И определяем, что других экземпляров не запущено
    }
    semaphore.release();        // Опускаем семафор

    // Если уже запущен один экземпляр приложения, то сообщаем об этом пользователю
    // и завершаем работу текущего экземпляра приложения
    if (is_running)
    {
        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Warning);
        msgBox.setText(QObject::trUtf8("Приложение уже запущено.\n"
                        "Вы можете запустить только один экземпляр приложения."));
        msgBox.exec();
        return 1;
    }

    MainWindow w;
    w.show();

    return a.exec();
}

Бейне оқулық

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

IscanderChe
  • Қар. 25, 2018, 3:49 Т.Ж.

День добрый.
Подскажите, как с помощью этих примеров вместо вывода сообщения сделать активным окно запущенного экземпляра приложения?

Evgenii Legotckoi
  • Қар. 25, 2018, 12:20 Т.Қ.

Добрый день!

С помощью API целевой системы придётся найти нужный процесс и открыть окно. Но придётся писать платформозависимый код. В случае Windows нужно смотреть, как с помощью WinAPI искать процессы и пытаться открыть их окна, если они есть. В случае Linux там ещё сложнее, или через XLib, или через DBus, но я не уверен, как именно это делается.

IscanderChe
  • Қар. 25, 2018, 1:24 Т.Қ.

Понятно. Спасибо!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
m
  • molni99
  • Қаз. 26, 2024, 1:29 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:20ұпай,
  • Бағалау ұпайлары-10
Соңғы пікірлер
i
innorwallҚар. 13, 2024, 11:03 Т.Қ.
Qt тілінде ойын қалай жазылады - 3-сабақ. Басқа объектілермен әрекеттесу what is priligy tablets What happens during the LASIK surgery process
i
innorwallҚар. 13, 2024, 8:09 Т.Қ.
C++ файлдарының ішінде CMakeLists.txt ішінде жарияланған айнымалы мәндерді пайдалану where can i buy priligy online safely Tom Platz How about things like we read about in the magazines like roid rage and does that really
i
innorwallҚар. 11, 2024, 10:12 Т.Қ.
Django - Оқулық 055. Автоматты толтыру өрісі функциясын қалай жазу керек Freckles because of several brand names retin a, atralin buy generic priligy
i
innorwallҚар. 11, 2024, 6:23 Т.Қ.
QML - Сабақ 035. C++ қолданбай QML тілінде сандарды пайдалану priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
i
innorwallҚар. 11, 2024, 3:50 Т.Қ.
Qt/C++ - 052-сабақ. Qt аудио ойнатқышын AIMP стилінде теңшеу It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
Енді форумда талқылаңыз
i
innorwallҚар. 13, 2024, 6:52 Т.Қ.
добавить qlineseries в функции PMID 35774217 Free PMC article priligy cvs
i
innorwallҚар. 11, 2024, 10:55 Т.Ж.
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз