从PHP工作进程到Python线程

3
现在我正在每台机器上运行50个PHP(以CLI模式)的单独工作进程,等待接收它们的工作负载(任务)。例如,调整图像大小的工作。在工作负载中,它们会接收到图像(二进制数据)和所需的大小。工作进程完成它的工作并返回调整大小后的图像。然后等待更多的工作(以一种聪明的方式循环)。我假设我加载和实例化了相同的可执行文件、库和类50次。我这样做正确吗?因为这听起来不是很有效。
现在我想要一个处理所有这些工作并能够使用所有可用CPU核心的进程,同时只加载一次所有内容(以提高效率)。我假设为每个工作启动一个新线程,并在其完成后停止该线程。如果有少于50个线程正在工作,则可以接受更多工作。如果所有50个线程都忙碌,将不接受任何其他工作。
我使用了许多库(用于Memcached、Redis、MogileFS等),以便访问系统使用的各种组件,而Python几乎是除了PHP之外唯一支持所有这些库的语言。
Python能否实现我的要求,并且它是否比当前的PHP解决方案更快更高效?
3个回答

4

Linux有共享库,因此这50个php进程大多使用相同的库。你似乎根本没有任何问题。

"这听起来不太有效。"不是一个问题描述,如果没有真正的原因,编写代码就是浪费时间和/或金钱。

Python是一种很好的语言,不会比php表现更差。Python的multiprocessing模块也可能会有很大的帮助。但是,如果php实现不完全疯狂,那么几乎没有什么可获得的。所以,当一切正常工作时,为什么要花时间去做呢?通常这是目标,而不是重写的原因...


1
虽然这是正确的,但它只适用于代码部分。假设所需的库分配了X字节的私有数据,其中50%在执行期间永远不会更改。 50个php进程将共享代码+分配50 * X。 Python库将分配X,在分叉后仅使用(X / 2 + 50 * X / 2),因为它还将共享未更改的数据。百分比当然取决于库。 X可能非常接近0,以至于没有区别,但另一方面它可能相当高... - viraptor

4
很有可能是的。但不要假设您必须进行多线程处理。看看multiprocessing模块。它已经包含了一个实现池的实现,这就是您可以使用的内容。它基本上解决了GIL问题(多线程一次只能运行一个“标准Python代码”-这是一个非常简化的解释)。
它仍然会为每个作业派生一个进程,但以不同的方式而不是重新开始。在进入工作进程之前完成的所有初始化和加载的库都将以写时复制的方式继承。您不会进行比必要更多的初始化,并且如果与预池状态没有实际区别,则不会浪费相同的库/类的内存。
因此,是的-仅查看此部分,Python将浪费更少的资源,并使用更好的工作池模型。是否真正更快/更少地滥用CPU,很难在没有测试或至少查看代码的情况下确定。请自己尝试。
补充:如果您担心内存使用情况,Python也可能帮助您一些,因为它具有“适当”的垃圾收集器,而在php中,GC不是优先考虑的,也不是那么好(有很好的原因)。

1

如果您使用的是正常的操作系统,那么共享库应该只加载一次,并在使用它们的所有进程之间共享。数据结构和连接句柄的内存显然会被复制,但停止和启动系统的开销可能大于保持空闲时的开销。如果您正在使用类似Gearman的东西,即使处于空闲状态,让几个工作程序保持运行可能是有意义的,然后有一个持久性监控进程,如果所有当前工作程序都忙碌直到阈值(例如可用CPU数量),则启动新的工作程序。然后,该进程可以按LIFO方式杀死长时间处于空闲状态的工作程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接