.pid 文件的作用

2,335 阅读1分钟

一些服务进程在在启动的时候会生成一个.pid文件, 里面包含了当前进程的pid. 这个.pid文件主要有两种作用:

  1. 方便杀死/重启当前进程
  2. 通过添加文件锁实现对该文件的互斥访问, 防止生成多个进程.

使用python的fcntl模块模拟实现

import os
import sys
import time
import fcntl
from signal import signal, SIGHUP, SIGTERM, SIGINT

import fire


class Server:

    def __init__(self, pidfile):
        self.pidfile = pidfile
        self.setup()

    def setup(self):
        print(f'setup pid {os.getpid()}')
        self.fileno = open(self.pidfile, 'w')
        self.fileno.write(str(os.getpid()))
        self.fileno.flush()
        fcntl.flock(self.fileno, fcntl.LOCK_EX | fcntl.LOCK_NB)

    def shutdown(self):
        print('shutdown')
        fcntl.flock(self.fileno, fcntl.LOCK_UN)
        self.fileno.close()
        os.remove(self.pidifle)
        sys.exit(0)

    def run(self):
        while True:
            print(f'running pidfile {self.pidfile} pid {os.getpid()}')
            time.sleep(3)


def main(pidfile_path):
    server = Server(pidfile_path)
    server.run()
    signal(SIGHUP, lambda s, f: server.restart())
    signal(SIGTERM, lambda s, f: server.stop())
    signal(SIGINT, lambda s, f: server.stop())


if __name__ == '__main__':
    fire.Fire(main)

通过下面命令启动该服务

python pythonpid.py ./pid.pid

然后再次启动的时候会报错

BlockingIOError: [Errno 35] Resource temporarily unavailable

如果想要停止该服务,用到下面的命令

kill -SIGTERM $(cat pid.pid)