我想在我的Django应用程序被Gunicorn/uWSGI分叉后,添加一个postfork函数来修补我的程序。
现在的问题是我知道我可以通过添加@postfork装饰器来做到这一点,但我认为它也可以通过使用Python 3.7os.register_at_fork
来实现,事实证明该函数从未被调用,甚至在fork发生之前注册?(或者我在已经发生分叉的时候注册函数太晚了?)我很想知道register_at_fork是如何工作的)
我的wsgi.py如下所示,我用我得到的所有东西测试了它,但似乎钩子函数从未在分叉的服务器worker中调用过。我很感谢你在这个问题上的帮助。
顺便说一句,使用@postfork装饰器,正如注释出来的那样,工作得很好。
# from uwsgidecorators import postfork
# @postfork
def hook():
# do something here
print('hello')
...
if hasattr(os, 'register_at_fork'):
print('registered')
os.register_at_fork(after_in_child=hook)
else:
print('not registered')
# os.fork()
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pollme.settings')
application = get_wsgi_application()
我的start命令是
uwsgi --die-on-term
--http 0.0.0.0:8000
--http-manage-expect
--master
--workers 3
--enable-threads
--threads 3
--manage-script-name
--wsgi-file myapplication/wsgi.py
我猜它可能与这个记录的行为有关,但我不能确定,我希望有人能帮助我理解是否gunicorn/uwsgi分叉被认为是"子进程启动"。
这些调用仅在期望控制返回给Python解释器时进行。典型的子进程启动不会触发它们,因为子进程不会重新进入解释器。
在fork之前注册执行的函数以反向注册顺序调用。在fork(父进程或子进程)之后注册执行的函数将按照注册顺序调用。
看起来uwsgi是从C代码派生出来的,python声明这种情况可能无法工作。uwsgi手动调用在装饰器@postfork
中注册的钩子,这就是为什么它们工作在uwsgi源代码中。我认为在uwsgi中有一些东西也只在某些条件下调用os.register_at_fork
注册的钩子(不确定具体是什么时候)。