简体   繁体   English

Python 多处理池挂在 ubuntu 服务器上

[英]Python multiprocessing Pool hangs on ubuntu server

I'm running Django on an Ubuntu server with nginx and gunicorn.我在带有 nginx 和 gunicorn 的 Ubuntu 服务器上运行 Django。 I'm trying to do some multiprocessing which is working on my local machine but hangs until the gunicorn worker times out on my server.我正在尝试做一些在我的本地机器上工作的多处理,但在我的服务器上的 gunicorn 工人超时之前挂起。

cpu_count = int(multiprocessing.cpu_count())
pool = Pool(processes = cpu_count)
result = pool.map_async(apiSimulAvail, rate_ranges)
result.wait()

...do some more stuff once all processes return

It hangs at pool = Pool(processes = cpu_count) .它挂在pool = Pool(processes = cpu_count) I don't get any errors, the gunicorn worker just times out and reboots.我没有收到任何错误,gunicorn 工人只是超时并重新启动。

Any indication as to why this is happening and/or how I can solve it is greatly appreciated.任何关于为什么会发生这种情况和/或我如何解决它的迹象都非常感谢。 Thanks.谢谢。

This seems to be a variation on Using python's Multiprocessing makes response hang on gunicorn so possibly this is a dupe.这似乎是Using python's Multiprocessing make response hang on gunicorn 的一个变体,所以这可能是一个骗局

That said do you have to use multiprocessing (MP)?那是说您必须使用多处理 (MP) 吗? You might honestly be better served farming this out to something like Celery.老实说,你可能会得到更好的服务,把它种植到像芹菜这样的东西上。 MP might be getting killed with the gunicorn worker when it dies since it owns the MP process. MP 可能会在 gunicorn 工人死亡时被杀死,因为它拥有 MP 进程。 Depending on the server config, that could happen pretty frequently.根据服务器配置,这可能会经常发生。 If you've got some very long running kind of job you can still farm that out to Celery, it's just a bit more configuration.如果你有一些运行时间很长的工作,你仍然可以把它交给 Celery,这只是更多的配置。

Are you using some async Gunicorn worker?你在使用一些异步 Gunicorn 工人吗? If so, try the default sync worker and see if you can reproduce the problem.如果是这样,请尝试使用默认的同步工作器,看看是否可以重现该问题。

If the problem can only be reproduced when using async workers, you should make sure the multiprocessing module is patched correctly.如果问题只能在使用异步工作者时重现,则应确保正确修补multiprocessing模块。

Change改变

pool = Pool(processes = cpu_count)

to

pool = Pool(cpu_count)

This assumes that you've imported Pool from multiprocessing otherwise you'll need to do这假设您已从多处理导入 Pool 否则您需要执行

multiprocessing.Pool(cpu_count)

I had a similar problem.我有一个类似的问题。 I solved it by giving each gunicorn worker a fixed amount of tasks to execute setting maxtasksperchild argument like this Pool(..., maxtasksperchild=1) .我通过为每个 gunicorn 工人提供固定数量的任务来执行设置maxtasksperchild参数来解决它,例如Pool(..., maxtasksperchild=1) In this way each gunicorn worker is freed up automatically after completing the given tasks.通过这种方式,每个 gunicorn 工人在完成给定的任务后会自动释放。

This is what Pool documentation tells:这是 Pool文档所说的:

Worker processes within a Pool typically live for the complete duration of the Pool's work queue.池中的工作进程通常在池的工作队列的整个持续时间内都存在。 A frequent pattern found in other systems (such as Apache, mod_wsgi, etc) to free resources held by workers is to allow a worker within a pool to complete only a set amount of work before being exiting, being cleaned up and a new process spawned to replace the old one.在其他系统(例如 Apache、mod_wsgi 等)中发现的一种常见模式,用于释放工作人员持有的资源,是允许池中的工作人员在退出、清理和产生新进程之前仅完成一定数量的工作替换旧的。 The maxtasksperchild argument to the Pool exposes this ability to the end user. Pool 的 maxtasksperchild 参数向最终用户公开了这种能力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM