//go:build linux package process import ( "fmt" "os" "path/filepath" "time" "golang.org/x/sys/unix" ) // Lock 获取进程间互斥锁 (Linux: flock) func (pm *ProcessManager) Lock() error { pm.mu.Lock() defer pm.mu.Unlock() if pm.locked { return nil } lockPath := filepath.Join(pm.dataDir, LockFileName) if err := os.MkdirAll(pm.dataDir, 0755); err != nil { return fmt.Errorf("创建数据目录失败: %w", err) } file, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0644) if err != nil { return fmt.Errorf("打开锁文件失败: %w", err) } start := time.Now() for { err := unix.Flock(int(file.Fd()), unix.LOCK_EX|unix.LOCK_NB) if err == nil { pm.lockFile = file pm.locked = true return nil } if err != unix.EWOULDBLOCK { file.Close() return fmt.Errorf("获取锁失败: %w", err) } if time.Since(start) > LockAcquireTimeout { file.Close() return fmt.Errorf("获取锁超时 (超过 %v)", LockAcquireTimeout) } time.Sleep(LockRetryInterval) } } // Unlock 释放互斥锁 (Linux: flock) func (pm *ProcessManager) Unlock() error { pm.mu.Lock() defer pm.mu.Unlock() if !pm.locked { return nil } if pm.lockFile != nil { unix.Flock(int(pm.lockFile.Fd()), unix.LOCK_UN) pm.lockFile.Close() pm.lockFile = nil } pm.locked = false return nil }