如何在Linux下使用Python Service模块轻松创建守护进程
轻松创建python守护进程

守护进程是在后台运行且脱离终端的进程。它脱离终端,是为了避免在执行过程中的信息在终端上显示。并且,该进程不会被任何终端所产生的终端信息打断。若要在 linux 系统下开启一个守护进程,可使用 nohup python task.py & 的方式。这种方法虽可行,但存在不方便之处。
启动后查看进程状态不方便,kill 进程时需先使用 ps 命令查看进程 pid,接着使用 kill 命令来杀掉进程。nohup 方式不能确保一个任务只有一个进程,多次使用会产生多个进程,而对于只能有一个进程的任务而言,这是很危险的。
想要轻松创建 python 守护进程,推荐使用 service 模块。此模块基于 python-daemon 库构建,能提供更加灵活的操作方式,并且可以通过 pip 进行安装。
pip install service
编写task.py脚本,内容如下
import time
import sys
from service import Service
def my_task():
"""
这是你的任务
"""
for i in range(10):
print('ok')
time.sleep(5)
class TaskService(Service):
初始化自身,接收任意数量的位置参数和关键字参数。
TaskService 的父类的构造函数被调用,传入了位置参数 *args 和关键字参数 **kwargs 。 即通过 super 函数调用了父类的构造函数,并传递了相应的参数。
def run(self):
my_task()
if __name__ == '__main__':
if len(sys.argv) != 2:
sys 退出并显示提示信息,提示信息为:语法:%s COMMAND,其中 %s 会被 sys.argv[0] 所替换。
cmd = sys.argv[1].lower()
service 被创建为 TaskService('my_service', pid_dir='/tmp')
if cmd == 'start':
service.start()
elif cmd == 'stop':
service.stop()
elif cmd == 'kill':
service.kill()
elif cmd == 'pid':
print(service.get_pid())
elif cmd == 'status':
if service.is_running():
print("Service is running.")
else:
输出:“服务未运行。”
else:
系统退出,原因是未知命令“%s”。% cmd
创建 Service 对象时,要指定服务的 name。同一个 name 只会有一个守护进程。pid_dir 默认的目录是/var/run。进程启动后会生成一个 my_service.pid 的文件,该文件的内容就是守护进程的 pid。当进程结束时,这个文件会被删除。
stop 方法的特点在于会发送 SIGTERM 信号,此信号能够被进程忽略,并且进程还可以接收该信号来进行一些收尾工作之后再退出;而 kill 方法发送的是 SIGKILL 命令,进程会立刻终止,这是一种极为稳定的终止进程的方式。
如果你启动守护进程使用了 service,那么必须使用 service 提供的 stop 或者 kill 来终止进程。如果你直接用 kill -9 pid 的方式终止进程,那么 my_service.pid 就不会被删除,下一次启动时就会报错,因为 service 是根据是否存在 my_service.pid 文件来判断进程是否存在的。