🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 进程锁 - 通过记录一个PID文件,避免两个进程同时运行的文件锁 - 进程锁的作用之一就是可以协调进程的运行 ### PID文件锁 - 方便进程向自己发停止或者重启信号 示例1: Nginx编译时可指定参数`--pid-path=/var/run/nginx.pid` 进程起来后就会把当前的PID写入这个文件,当然如果这个文件已经存在了,也就是前一个进程还没有退出,那么Nginx就不会重新启动 示例2: 进程管理工具Supervisord也是通过记录进程的PID来停止或者拉起它监控的进程的 ## 使用进程锁 - 操作系统默认不会为每个程序创建进程锁 - 通过文件就可以实现一个进程锁 - 例如程序开始运行时去检查一个PID文件,如果文件存在就直接退出,如果文件不存在就创建一个,并把当前进程的PID写入文件中。这样我们很容易可以实现读锁,但是所有流程都需要自己控制 ### flock接口 - 当然根据DRY(Don't Repeat Yourself)原则,Linux已经为我们提供了flock接口 - Flock提供的是advisory lock,也就是建议性的锁 go的示例 Go 1.3引入的`FcntlFock()` ``` // Control the lock of file. func fcntlFlock(lockType int16, path ...string) error { var err error if lockType != syscall.F_UNLCK { mode := syscall.O_CREAT | syscall.O_WRONLY lockFile, err = os.OpenFile(path[0], mode, 0666) if err != nil { return err } } lock := syscall.Flock_t{ Start: 0, Len: 1, Type: lockType, Whence: int16(os.SEEK_SET), } return syscall.FcntlFlock(lockFile.Fd(), syscall.F_SETLK, &lock) } // Lock the file. func Flock(path string) error { return fcntlFlock(syscall.F_WRLCK, path) } // Unlock the file. func Funlock(path string) error { err := fcntlFlock(syscall.F_UNLCK) if err != nil { return err } else { return lockFile.Close() } } ```