1. 程式人生 > >實現QT單例程式 QSystemSemaphore QSharedMemory

實現QT單例程式 QSystemSemaphore QSharedMemory

有的時候我們編寫的專案,需要單例執行的功能,下面採用QT共享記憶體的方式實現單例程式:

int main(int argc, char *argv[]) {
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    // 訊號量的意義,把操作共享記憶體的程式碼鎖住。因為有可能同時點選2次APP, 防止併發
    QSystemSemaphore sema("SingleApp Key", 1, QSystemSemaphore::Open);
    sema.acquire();

#ifdef Q_OS_LINUX
    /* Windows平臺上不存在應用程式崩潰後,共享記憶體段還存在的情況
     * LINUX應用程式崩潰後,共享記憶體段不會自動銷燬,則該程式再次執行會出問題
     * 所以程式啟動時先去檢查是否有程式崩潰後還存留的共享記憶體段,如果有,先銷燬,再建立
     */
    QSharedMemory mem("SingleApp");
    // 嘗試將程序附加到共享記憶體段
    if (mem.attach()) {
        // 將共享記憶體與主程序分離, 如果此程序是附加到共享儲存器段的最後一個程序,則系統釋放共享儲存器段,即銷燬內容
        mem.detach();
    }
#endif

    /*
     * 每個App開啟的時候,獲取一次共享記憶體。
     * 如果獲取失敗,說明是第一個啟動的APP,直接建立共享記憶體就好了。
     * 如果獲取成功,說明不是第一個,直接退出就好了。
     * 保證App在系統裡只能開啟一個。
     */
    QSharedMemory unimem("SingleApp");
    bool isRunning = false;
    if (unimem.attach()) {
        isRunning = true;
    } else {
        unimem.create(1);
        isRunning = false;
    }

    sema.release();

    if (isRunning) {
        qWarning() << QStringLiteral("已經有一個SingleApp在執行,即將退出");
        exit(0);
    }

    return app.exec();
}