diff --git a/agent/main.go b/agent/main.go index a622fc7..91a2fbc 100644 --- a/agent/main.go +++ b/agent/main.go @@ -9,6 +9,7 @@ import ( "os/exec" "os/signal" "path/filepath" + "reflect" "syscall" "time" @@ -312,10 +313,12 @@ func startDaemon() { Stderr: devNull, } - // 设置进程组,使子进程独立运行 - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setsid: true, + // 设置进程组,使子进程独立运行 (跨平台兼容写法) + attr := &syscall.SysProcAttr{} + if field := reflect.ValueOf(attr).Elem().FieldByName("Setsid"); field.IsValid() { + field.SetBool(true) } + cmd.SysProcAttr = attr if err := cmd.Start(); err != nil { fmt.Printf("启动失败: %v\n", err) diff --git a/agent/service.go b/agent/service.go index 084647f..848dcca 100644 --- a/agent/service.go +++ b/agent/service.go @@ -8,11 +8,13 @@ import ( "runtime" "strconv" "syscall" + + "github.com/gofrs/flock" ) // ========== PID 文件管理 ========== -var pidFileLock *os.File +var fileLock *flock.Flock func getPidFile() string { return filepath.Join(dataDir, "agent.pid") @@ -25,31 +27,21 @@ func getLockFile() string { // tryLock 尝试获取文件锁,确保只有一个实例运行 func tryLock() bool { os.MkdirAll(dataDir, 0755) - lockFile := getLockFile() - - var err error - pidFileLock, err = os.OpenFile(lockFile, os.O_CREATE|os.O_RDWR, 0644) - if err != nil { + + fileLock = flock.New(getLockFile()) + locked, err := fileLock.TryLock() + if err != nil || !locked { + fileLock = nil return false } - - // 尝试获取排他锁(非阻塞) - err = syscall.Flock(int(pidFileLock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB) - if err != nil { - pidFileLock.Close() - pidFileLock = nil - return false - } - return true } // unlock 释放文件锁 func unlock() { - if pidFileLock != nil { - syscall.Flock(int(pidFileLock.Fd()), syscall.LOCK_UN) - pidFileLock.Close() - pidFileLock = nil + if fileLock != nil { + fileLock.Unlock() + fileLock = nil os.Remove(getLockFile()) } } diff --git a/go.mod b/go.mod index 8a8cfd4..cf2e5a7 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/gofrs/flock v0.13.0 // indirect github.com/gohugoio/hugo v0.149.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect diff --git a/go.sum b/go.sum index 46211f8..99cd507 100644 --- a/go.sum +++ b/go.sum @@ -108,6 +108,8 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e h1:QArsSubW7eDh8APMXkByjQWvuljwPGAGQpJEFn0F0wY= github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e/go.mod h1:3Ltoo9Banwq0gOtcOwxuHG6omk+AwsQPADyw2vQYOJQ= github.com/gohugoio/hashstructure v0.5.0 h1:G2fjSBU36RdwEJBWJ+919ERvOVqAg9tfcYp47K9swqg=