Pidfile 存储了进程的进程 id。一般情况下 pidfile 有以下几个作用:
- 其他进程可以读取 pidfile 获取运行进程的 pid(当然也可以通过其他命令 动态获取)
- 在启动进程前先检查 pidfile,防止启动多个后台进程(特别像 agent 之类的)
下面是 docker 中管理 pidfile 的方法:
package main import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" log "github.com/sirupsen/logrus" ) func main() { _, err := NewPIDFile("pid.file") if err != nil { log.Errorf("error to create the pid file failed:%s", err.Error()) } } // PIDFile stored the process id type PIDFile struct { path string } // just suit for linux func processExists(pid string) bool { if _, err := os.Stat(filepath.Join("/proc", pid)); err == nil { return true } return false } func checkPIDFILEAlreadyExists(path string) error { if pidByte, err := ioutil.ReadFile(path); err == nil { pid := strings.TrimSpace(string(pidByte)) if processExists(pid) { return fmt.Errorf("ensure the process:%s is not running pid file:%s", pid, path) } } return nil } // NewPIDFile create the pid file // 指定路径下生产 pidfile, 文件内容为 pid func NewPIDFile(path string) (*PIDFile, error) { if err := checkPIDFILEAlreadyExists(path); err != nil { return nil, err } if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil { return nil, err } if err := ioutil.WriteFile(path, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil { return nil, err } return &PIDFile{path: path}, nil } // Remove remove the pid file func (file PIDFile) Remove() error { return os.Remove(file.path) }
Tips:
- 不同操作系统判断进程是否存在的方式是不一样的.文中的是检测 linux 下进程是否存在的方法