根据您的描述,我建议您继续为您的约 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 绑定的工作人员,那么您必须开始研究基于事件的框架,例如asyncio、Twisted、gevent、eventlet、greenlet等。这是因为每个 OS 线程或进程产生的预留内存成本,一旦你进入数千个实例,预留空间开始累加;另一方面,基于事件的系统不会产生多个线程,它们只是循环 I/O 设备接口并根据事件累积数据。您可以使用基于事件的网络支持非常大量的并发连接。
在 Windows 上,这里有一篇关于多线程和进程的测量限制的优秀文章。对文档的快速扫描告诉我,最大进程数的限制约为 10k。我在其他地方看到过这个问题 10k 问题,但我现在没有可用的参考资料。
如果您有大量受 CPU 限制的工作人员,那么您必须使用分布式计算,将工作推送到各种不同的机器上。 multiprocessing
通过 API 也支持这一点Manager
,但我对此没有个人经验。ZeroMQ 现在似乎很流行用于处理分布式消息传递。