確保程式僅運行單一進程實例,常見方案有 Mutex、檔案鎖、Remoting 等。利用 **PE 共享資料段** 是最簡潔、零依賴、極低開銷的原生技巧。
#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;
}
#pragma data_seg("Shared"):定義名為 Shared 的區段,變數 g_InstanceCount 放入其中#pragma comment(linker, "/SECTION:Shared,RWS"):鏈接器指令,賦予 Shared **Read/Write/Share** 屬性INC 在單核下天然原子;多核下需 InterlockedIncrement 保證跨核原子性| 優點 | 缺點 |
|---|---|
| 零核心物件,無 Mutex/信號量開銷 | 僅限同機器、同用戶會話(Session 0 隔離下服務無效) |
| 代碼極少,無外部依賴 | 無法傳遞啟動參數給現有實例(需另行 IPC) |
| 適用於 C/C++/Delphi/汇编等原生語言 | .NET 建議用 Mutex,托管層無直接對應機制 |
static Mutex _mutex = new Mutex(true, "{GUID}", out bool createdNew);
if (!createdNew) return;
Application.Run(new MainForm());
跨會話、支援參數傳遞、框架原生支援,推薦用於 .NET 應用。
共享資料段是原生開發中「單實例」的極簡藝術:幾行指令,一個變數,無鎖、無核心調用、無併發競態(單指令原子)。理解 PE 載入機制,方能駕輕就熟運用此技。