进程单例
以下是一篇跨平台进程单实例技术调研及实现方案,包含Windows/Linux/macOS三平台兼容的C++代码实现:
跨平台进程单实例技术实现
一、技术背景
-
进程单实例控制是保证关键服务唯一性的核心技术,常见于系统守护进程、桌面应用程序等场景。本文通过三种系统级机制实现跨平台支持:
-
Windows:内核对象互斥体
-
Linux/macOS:文件锁机制
-
通用方案:跨进程内存共享
二、实现方案
方案一:跨平台文件锁(推荐)
#include <iostream>
#include <string>
#include <cstdlib>#if defined(_WIN32)
#include <Windows.h>
#else
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#endifclass SingleInstance {
public:SingleInstance(const std::string& lockName) {
#if defined(_WIN32)// Windows命名互斥体hMutex = CreateMutexA(NULL, TRUE, lockName.c_str());isRunning = (GetLastError() == ERROR_ALREADY_EXISTS);
#else// Unix系文件锁std::string lockPath = "/tmp/" + lockName + ".lock";fd = open(lockPath.c_str(), O_CREAT | O_RDWR, 0666);isRunning = (flock(fd, LOCK_EX | LOCK_NB) != 0);
#endif}~SingleInstance() {
#if defined(_WIN32)if(hMutex) {ReleaseMutex(hMutex);CloseHandle(hMutex);}
#elseif(fd >= 0) {flock(fd, LOCK_UN);close(fd);}
#endif}bool isAnotherRunning() const { return isRunning; }private:
#if defined(_WIN32)HANDLE hMutex = NULL;
#elseint fd = -1;
#endifbool isRunning = false;
};// 使用示例
int main() {SingleInstance si("my_app");if(si.isAnotherRunning()) {std::cerr << "Application already running!" << std::endl;return EXIT_FAILURE;}// 主程序逻辑std::cout << "Application started successfully" << std::endl;std::cin.get(); return EXIT_SUCCESS;
}
方案二:共享内存检测
// Windows实现
#ifdef _WIN32
#include <windows.h>class WinSharedMem {
public:WinSharedMem(const char* name) {hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, name);exists = (GetLastError() == ERROR_ALREADY_EXISTS);}// ... 其他成员函数
};
#endif// Linux/macOS实现
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <fcntl.h>class UnixSharedMem {
public:UnixSharedMem(const char* name) {fd = shm_open(name, O_CREAT | O_RDWR, 0666);exists = (errno == EEXIST);}// ... 其他成员函数
};
#endif
三、关键实现点
- Windows核心机制
使用CreateMutexA创建命名互斥体
通过GetLastError()检测ERROR_ALREADY_EXISTS
需显式释放互斥体资源 - Linux/macOS实现
采用flock()文件锁实现进程排他
锁文件存储在/tmp目录保证可写性
文件描述符自动回收机制 - 跨平台封装
使用预处理器指令区分平台
统一接口isAnotherRunning()
RAII模式管理资源生命周期
四、测试验证
Linux/macOS编译
g++ -std=c++11 singleton.cpp -o singleton
Windows编译(VS开发者命令提示)
cl /EHsc singleton.cpp
五、方案对比
特性 | 文件锁方案 | 共享内存方案 |
---|---|---|
跨平台性 | 优秀 | 需平台特定实现 |
可靠性 | 高(内核级锁) | 中等 |
资源消耗 | 低 | 较高 |
实现复杂度 | 简单 | 复杂 |
完整代码库可参考的实现模式,建议优先采用文件锁方案作为基础实现。实际部署时需注意权限管理(如Linux下的/tmp目录权限)和异常处理(如进程崩溃后的锁释放机制)。
完整代码
Github
作者 | 郑天佐 | |
邮箱 | zhengtianzuo06@163.com | |
主页 | http://www.zhengtianzuo.com | |
github | https://github.com/zhengtianzuo |