【问题标题】:How expensive is to have a lot of processes, spawned by multiprocessing module?由多处理模块产生的大量进程有多昂贵?
【发布时间】:2018-03-10 19:36:03
【问题描述】:

我有一个应用程序,其中有 2 个子进程(RabbitMQ consumerRabbitMQ producer)不断运行(大部分时间它们处于空闲状态)。但我还需要根据RabbitMQ consumer 进程的条件生成另一个N 子进程数量(我们称之为Worker process)。

所以Worker processes 非常轻量级,不会进行大量计算,但是乳清的工作需要很长时间(最多一个小时)。机器本身不会有超过 4 个 CPU 内核。我计划在CentOS 上运行该应用程序。所以问题是:是否可以有很多(我预计从 1 到 20 个)这样的轻量级进程来来去去,并且大部分时间都处于空闲状态?

我的第一个想法是创建一个子进程(Worker process),然后在里面使用线程。但是我听说有人很难将multiprocessingthreading 模块混合在一起。是真的吗?

顺便说一句,我的应用是在 Python 2.7 中,为了产生子进程,我使用 multiprocessing 模块。

【问题讨论】:

  • 20 个进程不算什么,因为它们是轻量级的。
  • 我的情况和你一样。进行不同的测试,我发现 20 什么都不是。所以我提高了这个数字,直到我的电脑在不到两分钟的时间内无法创建池,大约 4000 个子进程。根据测试结果,完美数字是 500

标签: python multithreading centos multiprocessing


【解决方案1】:

根据您的描述,我建议您继续为您的大约 20 个工作创建多个流程。 multiprocessing API 让这一切变得非常简单,您最宝贵的资源就是您自己的时间。并发编程的复杂性很快就会失控,因此您需要获得所有帮助。

详情

如果您的工作进程是I/O 绑定,那么(可以说)拥有许多进程不会对 CPU 造成影响。我的 Windows 当前列出了 145 个正在运行的进程,尽管我们认为这台机器处于空闲状态。只需确保您的代码定期调用time.sleep(x),其中x 是轮询的“合理”暂停时间,或者您正在使用为您执行此操作的库,例如多处理的连接对象及其 .poll(x) 方法。

如果您的工作进程是 CPU 受限,那么恐怕您最好设置一个大小等于可用 CPU 的进程池,然后将作业推送到队列中并让池中的进程将作业从队列中取出。 multiprocessing 非常支持这种范例。

如果工作人员可能在不同时间同时受到 CPU 限制和 I/O 限制,这会变得很棘手。在这种情况下,我建议您保留一个进程(专用)用于 CPU 工作,让它从队列中取出作业,然后让许多其他(I/O)进程创建作业并将它们推送到工作队列中。如果工作的速度超过了您的一个 CPU 内核可以处理的速度,您可以添加第二个专用内核,或者在队列上设置一个 maxsize 并让 I/O 工作人员监控队列大小以了解是否可以添加新作品。

如果您有大量受 I/O 限制的工作人员,那么您必须开始研究基于事件的框架,例如 asyncioTwistedgevent、@ 987654324@、greenlet 等等。这是因为每个 OS 线程或进程产生的预留内存成本,一旦你进入数千个实例,预留空间开始累加;另一方面,基于事件的系统不会产生多个线程,它们只是循环 I/O 设备接口并根据事件累积数据。您可以通过基于事件的网络支持大量并发连接。

在 Windows 上,有一篇关于多线程和进程的测量限制的优秀文章here。对文档的快速扫描告诉我,最大进程数的限制约为 10k。我在其他地方看到过这个问题,10k 问题,但我现在没有可用的参考资料。

如果您有大量受 CPU 限制的工作人员,那么您必须使用分布式计算,将作业推送到各种不同的机器上。 multiprocessing 也通过 Manager API 支持此功能,但我对此没有个人经验。 ZeroMQ 现在似乎很流行用于处理分布式消息传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    相关资源
    最近更新 更多