//go:build !windows package instance import ( "errors" "os" "syscall" ) type unixInstanceLock struct { file *os.File } // tryAcquireInstanceLock 用 flock 非阻塞独占锁文件。 // 第二个参数表示「锁被别的进程持有」,此时调用方应继续扫描下一个槽位。 func tryAcquireInstanceLock(path string) (instanceLock, bool, error) { file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600) if err != nil { return nil, false, err } if err := syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { _ = file.Close() if errors.Is(err, syscall.EWOULDBLOCK) || errors.Is(err, syscall.EAGAIN) { return nil, false, nil } return nil, false, err } return &unixInstanceLock{file: file}, true, nil } func (l *unixInstanceLock) Close() error { if l == nil || l.file == nil { return nil } _ = syscall.Flock(int(l.file.Fd()), syscall.LOCK_UN) return l.file.Close() }