django为什么需要子进程
一旦用户用manage.py runserve
r启动开发服务器,就启动了一个django的进程,当然如果我们用ps aux
,这其实是一个Python进程,不过他运行了manage.py而已。这个启动的django进程并没有直接就开始作为Http Server来Listen 8000端口,而是创建了一个和自己一模一样的子进程。是子进程真正监听了端口号
为什么呢?因为django要方便,当开发人员每次修改Python源文件的时候,在网页上能够立刻看到效果。
这个子进程已启动会检查自己是否一个子进程,如果是的话开始调用一个inner_run的函数,这个函数开始Listen 8000
端口,作为Http Server开始服务。如果开发人员没有Python代码,一切都OK,如果django父进程发现Python代码被修改,他会重启这个子进程,重装如Python代码,这样修改后的Python代码就会在网页上体现出来了。
注:
同时用kill杀死子进程的时候,父进程也会消失
,
而杀死父进程的时候,子进程还在
,说明django中是父进程一直在监控子进程的修改。
以下是证明例子:
/usr/bin/python3.8 /home/szr/lzztes/manage.py runserver 0.0.0.0:8000
命定启动django后,ps aux
可以发现有创建了两个进程号为13866和13868的进程,且13868的状态为sl+,说明是休眠状态,多线程(克隆线程),且是后台进程
。
使用sudo lsof -i:8000
监听8000端口,发现是子进程13868
监听的
通常调试的django进程是django的父进程,而这个父进程并不是真正的Http Server,真正的Http Server是子进程。所以我们在代码中下的断点是永远不会被运行的,因为代码是那个子进程中运行的。 所以让django不产生子进程,让父进程直接作为Http Server来运行,通过python manage.py runserver --noreload
来执行
执行结果如下,/usr/bin/python3.8 /home/szr/lzztes/manage.py runserver 0.0.0.0:8000 --noreload
命定启动django后,发现只启动了父进程14271,状态是S+,并且该父进程作为真正的Http Server来监听8000端口。
如何关闭子进程
此方法启动开发服务器时,如果对python代码进行修改,则服务器会自动重启。
python manage.py runserver
Django的内置开发服务器默认启用了自动重载功能,它生成一个新线程
作为重新加载代码
的方法。不想开启子进程可以执行以下操作,此方法启动开发服务器时,对django项目python代码修改,服务器不会自动重启:
python manage.py runserver --noreload
附: 在Linux中的状态:
D 不可中断 Uninterruptible sleep (usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核2.6开始无效)
X 死掉的进程
< 高优先级
N 低优先级
L 有些页被锁进内存
s 包含子进程
+ 位于后台的进程组
l 多线程,克隆线程
根据以上信息,得知sl+
处于休眠状态,多线程(克隆线程),且是后台进程
。