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 Т.Қ.

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

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
OI
  • Ora Iro
  • Жел. 24, 2024, 5:38 Т.Қ.

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:40ұпай,
  • Бағалау ұпайлары-8
AD

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

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

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

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 10:51 Т.Қ.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚар. 1, 2024, 12:37 Т.Ж.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 6:19 Т.Қ.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 5:51 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 9:02 Т.Қ.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 25, 2024, 1:11 Т.Ж.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Қар. 15, 2024, 5:04 Т.Қ.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectМаусым 4, 2022, 1:49 Т.Қ.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimҚаз. 25, 2024, 7:10 Т.Қ.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

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