// Author: NiuJiuRu // Email: niujiuru@qq.com package baseapp import ( "fmt" "os" "os/signal" "path/filepath" "sync/atomic" "syscall" "github.com/alexflint/go-filemutex" ) var Version, BuildTime string // 由Makefile传入 var isExit atomic.Bool var exitCh = make(chan struct{}) var signalReady atomic.Bool func ModuleInit() { InitPath() InitLogger("") } func SingleInstanceRun() { // 非阻塞单实例运行, 调用此函数后, 安全退出时, 需调用SafeExit()函数 lockFile := filepath.Join(RUN_DIR, EXEC_FILENAME+".lock") mux, err := filemutex.New(lockFile) if err != nil { Logger.Fatalf("An error occurred while calling the filemutex.New() function: %v", err) } if err = mux.TryLock(); err != nil { Logger.Warnf("Another instance is already running!") mux.Close() Logger.Infof("Exited") os.Exit(0) } pid := os.Getpid() err = os.WriteFile(lockFile, fmt.Appendf(nil, "%d", pid), 0644) if err != nil { Logger.Warnf("Can't to write PID to the \"%s\" file: %v!", lockFile, err) } ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) signalReady.Store(true) go func() { sig := <-ch Logger.Infof("Received signal: %v", sig) _ = mux.Close() _ = os.Remove(lockFile) isExit.Store(true) close(exitCh) }() } func IsExit1() bool { return isExit.Load() } func IsExit2() <-chan struct{} { return exitCh } func SafeExit() { // 安全退出 if !signalReady.Load() { return } pid := os.Getpid() syscall.Kill(pid, syscall.SIGTERM) <-exitCh }