我使用CherryPy,Apache和mod_wsgi建立了一个网站,除了一个问题外,一切都很棒。当用户操作要求自动发送电子邮件时,我有时会使用os.fork
,以便父进程可以立即返回并为用户提供" OK"消息,而子进程负责发送电子邮件(可能需要几秒钟,我不希望用户必须等待)。
当子进程完成其工作并调用sys.exit()
时,会出现问题。似乎mod_wsgi捕获SystemExit
异常,将回溯转储到我的Apache错误日志中,并使子进程保持运行。我有两个问题:
它混乱了Apache错误日志,其中的回溯并不代表实际出现错误的任何内容,
它使进程运行,浪费系统资源。更糟糕的是,这些睡眠过程中有多少会随着时间的推移而积累?
对于记录,Apache错误日志中的输出如下所示:
mod_wsgi (pid=14900): SystemExit exception raised by WSGI script '/Users/me/myscript.py' ignored.
后跟回溯到sys.exit()调用的回溯。
我想this解释了为什么SystemExit
例外由mod_wsgi捕获,但这对我没有帮助。
如果有一种方法可以配置mod_wsgi的行为,那将是很好的,但当我搜索" SystemExit"和" sys.exit"在the docs中,没有人出现任何事情。
搜索" mod_wsgi SystemExit"在这个网站上只收到六个帖子,而且他们都没有询问如何允许子进程退出。
有谁知道如何让子进程实际退出,并使mod_wsgi不会将任何内容转储到Apache错误日志中?
答案 0 :(得分:1)
一般来说,您不应在未创建的服务器进程中托管的代码中使用fork()
。它经常导致奇怪的流程生命周期问题,类似于您在此处描述的问题。 (这超出了Apache,WSGI或Python;它适用于各种各样的情况。)
如果是一个选项,我建议使用单独的工作队列来处理异步任务。对于Python,一个常用选项是Celery。
如果这绝对是不是选项,则可以绕过SystemExit
异常并通过调用os._exit()
立即退出Python。但是,请注意这可能仍然会导致一些奇怪的行为,我不会推荐它。