2

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

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

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

顺便说一句,我的应用程序在 Python 2.7 中,并且为了产生子进程,我使用了multiprocessingmodule.

4

1 回答 1

6

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

细节

如果您的工作进程是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 绑定的工作人员,那么您必须开始研究基于事件的框架,例如asyncioTwistedgeventeventletgreenlet等。这是因为每个 OS 线程或进程产生的预留内存成本,一旦你进入数千个实例,预留空间开始累加;另一方面,基于事件的系统不会产生多个线程,它们只是循环 I/O 设备接口并根据事件累积数据。您可以使用基于事件的网络支持非常大量的并发连接。

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

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

于 2013-10-10T23:19:02.800 回答