本文基于 django-2.1.x 版本系列编写。
初试 - 文件变化后 server 自动重启
在此之前,不妨先了解下
django是如何做到自动重启的
开始
django 使用 runserver 命令的时候,会启动俩个进程。
runserver 主要调用了 django/utils/autoreload.py 下 main 方法。  
至于为何到这里的,我们这里不作详细的赘述,后面篇章会进行说明。
主线程通过 os.stat 方法获取文件最后的修改时间进行比较,继而重新启动 django 服务(也就是子进程)。
大概每秒监控一次。
| 1 | python复制代码# django/utils/autoreload.py 的 reloader_thread 方法 | 
code_changed 根据每个文件的最好修改时间是否发生变更,则返回 True 达到重启的目的。
父子进程&多线程
关于重启的代码在 python_reloader 函数内
| 1 | python复制代码 | 
程序启动,因为没有 RUN_MAIN 变量,所以走的 else 语句块。
颇为有趣的是,restart_with_reloader 函数中使用 subprocess.call 方法执行了启动程序的命令( e.g:python3 manage.py runserver ),此刻 RUN_MAIN 的值为 True ,接着执行 _thread.start_new_thread(main_func, args, kwargs) 开启新线程,意味着启动了 django 服务。
如果子进程不退出,则停留在 call 方法这里(进行请求处理),如果子进程退出,退出码不是3,while 则被终结。反之就继续循环,重新创建子进程。
检测文件修改
具体检测文件发生改变的函数实现。
| 1 | python复制代码 | 
总结
以上就是 django 检测文件修改而达到重启服务的实现流程。
结合 subprocess.call 和 环境变量 创建俩个进程。主进程负责监控子进程和重启子进程。
子进程下通过开启一个新线程(也就是 django 服务)。主线程监控文件变化,如果变化则通过 sys.exit(3) 来退出子进程,父进程获取到退出码不是3则继续循环创建子进程,反之则退出整个程序。
好,到这里。我们勇敢的迈出了第一步,我们继续下一个环节!!! ヾ(◍°∇°◍)ノ゙
本文转载自: 掘金