假设我们有一个这样的系统:
______ { 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%.关于全局解释器锁和多线程的事情可能导致Python花费所有时间在线程之间切换,检查它们中是否有任何来自数据库的答案."因此最近单进程事件驱动的库增加了."
那是对的吗?Python应用程序服务线程在I/O延迟增加时是否实际使用更多 CPU ?
从理论上讲,在实践中,没有可能; 这取决于你在做什么.
有一整小时的视频和关于它的pdf,但实质上它归结为GIL的一些无法预料的后果,CPU与IO绑定线程与多核.基本上,等待IO的线程需要唤醒,因此Python开始"抢先"其他线程每个Python"滴答"(而不是每100个滴答).然后,IO线程无法从CPU线程中获取GIL,从而导致循环重复.
多数人过于简单,但这就是它的要点.视频和幻灯片包含更多信息.它在多核机器上表现出来并且是一个更大的问题.如果进程从os接收到信号(因为它也触发了线程切换代码),也可能发生这种情况.
当然,正如其他海报所说的那样,如果每个海报都有自己的流程,那就会消失.
巧合的是,幻灯片和视频解释了为什么有时候你不能在Python中使用CTRL + C.