1 Star 0 Fork 0

wait4me/selfGoLib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
singletonUtil.go 2.63 KB
一键复制 编辑 原始数据 按行查看 历史
// Package singletonUtil 提供单实例运行检测功能
// 使用文件锁机制确保同一时间只有一个程序实例在运行
package singletonUtil
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"log/slog"
"os"
"path/filepath"
"github.com/gofrs/flock"
)
// instanceLock flock 锁句柄,需要在程序退出时释放
var instanceLock *flock.Flock
// IsSingleton 检查当前程序是否只有一个实例在运行,使用文件锁机制
// 返回值:
//
// true - 当前程序是唯一运行的实例
// false - 检测到其他相同程序实例正在运行,或无法获取文件锁
//
// 机制说明:
// - 在系统临时目录创建基于程序路径的锁文件
// - 使用 github.com/gofrs/flock 库实现跨平台文件锁
// - 当程序正常退出时,锁会自动释放
//
// 使用示例:
//
// // 在 main 函数开头调用
// defer SingletonUtil.ReleaseInstanceLock()
// if !SingletonUtil.IsSingleton() {
// log.Fatal("程序已在运行")
// }
func IsSingleton() bool {
// 获取可执行文件路径
exePath, err := os.Executable()
if err != nil {
slog.Error("获取可执行文件路径失败", "error", err)
return false
}
// 解析符号链接获取真实路径
exePath, err = filepath.EvalSymlinks(exePath)
if err != nil {
slog.Error("解析可执行文件路径失败", "error", err)
return false
}
// 计算程序路径的哈希值作为锁文件名的一部分,避免路径过长
hasher := sha256.New()
hasher.Write([]byte(exePath))
pathHash := hex.EncodeToString(hasher.Sum(nil))[:16]
// 创建锁文件路径
tempDir := os.TempDir()
lockFilePath := filepath.Join(tempDir, fmt.Sprintf(".%s.lock", pathHash))
// 使用 flock 库创建锁文件
fileLock := flock.New(lockFilePath)
// 尝试获取排他锁(非阻塞模式)
locked, err := fileLock.TryLock()
if err != nil {
slog.Error("创建文件锁失败", "path", lockFilePath, "error", err)
return false
}
if !locked {
slog.Info("检测到程序已在运行", "lock_file", lockFilePath)
return false
}
// 将锁文件句柄保存到全局变量,确保程序退出时锁会释放
instanceLock = fileLock
slog.Debug("成功获取文件锁", "lock_file", lockFilePath)
return true
}
// ReleaseInstanceLock 释放实例锁(在程序退出时调用)
// 通常在 main 函数开头使用 defer 调用:
//
// defer SingletonUtil.ReleaseInstanceLock()
func ReleaseInstanceLock() {
if instanceLock != nil {
// Unlock 会释放锁并删除锁文件
if err := instanceLock.Unlock(); err != nil {
slog.Warn("释放文件锁失败", "error", err)
} else {
slog.Debug("已释放文件锁")
}
instanceLock = nil
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/wait4me/selfGoLib.git
git@gitee.com:wait4me/selfGoLib.git
wait4me
selfGoLib
selfGoLib
v1.0.3

搜索帮助