假设我们有这样一个系统:
______
{ application instances ---network--- (______)
{ application instances ---network--- | |
requests ---> load balancer { application instances ---network--- | data |
{ application instances ---network--- | base |
{ application instances ---network--- \______/
请求传入,负载均衡器将其发送到应用程序服务器实例,然后应用程序服务器实例与数据库(LAN 上的其他地方)对话。应用程序实例可以是单独的进程或单独的线程。为了涵盖所有基础,假设有几个相同的进程,每个进程都有一个相同的应用程序服务线程池。
如果数据库运行缓慢,或者网络陷入困境,显然请求服务的吞吐量会变得更糟。
现在,在我使用 Python 之前的所有经验中,这将伴随着应用程序实例的 CPU 使用率相应下降——它们将花费更多时间阻塞 I/O 和减少 CPU 密集型工作的时间。
但是,有人告诉我,对于 Python,情况并非如此——在某些 Python 环境下,这种情况会导致 Python 的 CPU 使用率上升,可能一直到 100 %。 Global Interpreter Lock 和多线程的某些问题可能会导致 Python 花费所有时间在线程之间切换,检查是否有任何线程从数据库中得到答案。 “因此最近出现了单进程事件驱动库。”
这样对吗?当 Python 应用程序服务线程的 I/O 延迟增加时,它们是否真的使用更多 CPU?
最佳答案
理论上,不,在实践中,这是可能的;这取决于你在做什么。
有一个完整的hour-long video和 pdf about it ,但本质上它归结为 GIL 与 CPU 与 IO 绑定(bind)线程与多核的一些不可预见的后果。基本上,等待 IO 的线程需要唤醒,因此 Python 开始在每个 Python“滴答声”(而不是每 100 个滴答声)“抢占”其他线程。然后 IO 线程无法从 CPU 线程获取 GIL,导致循环重复。
这过于简单化了,但这就是它的要点。视频和幻灯片包含更多信息。它在多核机器上表现出来并且是一个更大的问题。如果进程从操作系统接收到信号,也可能发生这种情况(因为这也会触发线程切换代码)。
当然,正如其他发帖人所说,如果每个人都有自己的流程,这种情况就会消失。
巧合的是,幻灯片和视频解释了为什么有时不能在 Python 中使用 CTRL+C。
关于python - 慢速网络会导致 Python 应用程序使用*更多* CPU 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1046873/