我有一个工作进程,它在启动时加载一个特殊的数据结构,然后定期加载。
但是,数据结构 - 第三方C ++模块 - 存在内存泄漏。
我尝试使用gunicorn“max_requests”设置让工作人员在这么多请求之后过期,这会清除他们的资源并重新加载数据结构。但是我有一些挑剔的问题,我不会进入。
我尝试添加一个os._exit(0),强制该worker停止(并重新加载),但这意味着该请求得到了错误响应。
我想做的是发出响应信号枪,然后杀死工作人员,就好像触发了“max_requests”标志一样。
有没有机制可以做到这一点?
答案 0 :(得分:1)
重新加载内置函数对于重新初始化模块非常有用,但在该函数的文档(http://docs.python.org/2/library/functions.html#reload)中,您会发现:"它是合法的,但通常不是除了sys, main 和 builtin 之外,重新加载内置或动态加载的模块非常有用。但是,在许多情况下,扩展模块不是设计为不止一次初始化,并且在重新加载时可能以任意方式失败。"换句话说,它可能无法解决您的问题。
但是,如果您能够将对第三方模块的调用移动到子进程中,则很容易确保每次都重新加载它,因为您现在通过在单独的进程中执行脚本来使用该模块。只需制作一个单独的py文件,例如do_something.py,您可以在其中执行子进程所需的所有操作。然后您可以使用以下命令运行此文件:
p = subprocess.Popen(
[sys.executable, 'do_something.py', arg1, arg2 ...],
stdout=subprocess.PIPE
)
其中' arg1,arg2,...'表示您可能需要传递给子流程的参数。如果需要读取C ++模块的输出,可以在do_something.py中打印,并使用以下命令在应用程序中读取它:
p.stdout.read()
我承认这不是一个特别顺利的解决方案,但我认为它应该有效。