首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

利用共享資料段實現 EXE 單實例運行:最輕量級方案

     編輯:關於.NET

確保程式僅運行單一進程實例,常見方案有 Mutex、檔案鎖、Remoting 等。利用 **PE 共享資料段** 是最簡潔、零依賴、極低開銷的原生技巧。

原理:PE Section 屬性控制

  • EXE 載入時,OS 為每個進程複製私有資料段(.data/.bss),隔離狀態
  • 若標記 Section 為 **可讀/可寫/共享 (RWS)**,所有進程映射**同一塊物理頁面**
  • 在共享段放置計數器,進程啟動時原子遞增,>1 即退出

實現代碼 (C/C++)


#pragma data_seg("Shared")
unsigned long g_InstanceCount = 0;
#pragma data_seg()

#pragma comment(linker, "/SECTION:Shared,RWS")

int main() {
    ++g_InstanceCount;
    if (g_InstanceCount > 1) {
        return 0; // 已有實例運行,靜默退出
    }

    // 正常業務邏輯
    // ...

    return 0;
}

關鍵點解析

  1. #pragma data_seg("Shared"):定義名為 Shared 的區段,變數 g_InstanceCount 放入其中
  2. #pragma comment(linker, "/SECTION:Shared,RWS"):鏈接器指令,賦予 Shared **Read/Write/Share** 屬性
  3. 原子性: 單指令 INC 在單核下天然原子;多核下需 InterlockedIncrement 保證跨核原子性
  4. 清理: 進程結束時 OS 自動釋放映射,計數器自然遞減(因所有進程共享同一記憶體)

優缺點權衡

優點缺點
零核心物件,無 Mutex/信號量開銷僅限同機器、同用戶會話(Session 0 隔離下服務無效)
代碼極少,無外部依賴無法傳遞啟動參數給現有實例(需另行 IPC)
適用於 C/C++/Delphi/汇编等原生語言.NET 建議用 Mutex,托管層無直接對應機制

.NET 替代方案


static Mutex _mutex = new Mutex(true, "{GUID}", out bool createdNew);
if (!createdNew) return;
Application.Run(new MainForm());

跨會話、支援參數傳遞、框架原生支援,推薦用於 .NET 應用。

總結

共享資料段是原生開發中「單實例」的極簡藝術:幾行指令,一個變數,無鎖、無核心調用、無併發競態(單指令原子)。理解 PE 載入機制,方能駕輕就熟運用此技。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved