coo*_*278 7 python multithreading python-multithreading python-multiprocessing
据我了解,GIL使得不可能拥有分别利用内核的线程。
这是一个基本问题,但是threading库的意义是什么?如果线程代码的速度与普通程序相当,这似乎没有用。
Bha*_*rel 18
尽管存在 GIL,线程库仍然运行良好。
在我解释之前,你应该知道Python的线程是真正的线程——它们是运行Python解释器的普通操作系统线程。GIL(或全局解释器锁)仅在运行纯Python代码时才被获取,并且在许多情况下被完全释放,甚至不被检查。
GIL不会阻止这些操作并行运行:
其中任何一个(以及更多)都可以以并行方式完美运行,并且在大多数程序中,这些是花费最长时间的较重部分。
在 Python 中构建一个获取天文数据并计算轨迹的示例 API 意味着:
基本上GIL不会影响绝大多数程序运行时。
此外,至少对于网络来说,目前其他方法更加流行,例如asyncio在同一线程上提供协作多任务处理,有效消除线程过载的缺点,并允许同时运行更多的连接。通过利用它,GIL 甚至不再相关。
GIL 可能是一个问题,并且在运行纯 Python 代码时占用 CPU 密集型的程序中,线程变得毫无用处,例如计算斐波那契数的简单程序,但在大多数现实情况下,除非您正在运行一个规模巨大的网站,例如与 Youtube(无可否认,它遇到了问题)一样,GIL 并不是一个重要的问题。
在某些情况下,应用程序甚至可能无法充分利用一个内核,而使用线程(或进程)可能有助于实现这一目标。
考虑一个典型的Web应用程序。它接收来自客户端的请求,对数据库进行一些查询,然后将数据返回给客户端。鉴于IO操作大多数时候都比CPU操作慢几个数量级,因此此类应用程序正在等待IO完成。首先,它等待从套接字读取请求。然后,它一直等到对数据库的请求写入打开到DB的套接字中。然后,它等待数据库的响应,然后将响应写入客户端套接字。
等待IO完成可能需要90%(或更长时间)的时间来处理请求。当单线程应用程序在IO上等待时,它只是不使用内核,并且该内核可用于执行。因此,这样的应用程序有空间让其他线程甚至在单个内核上执行。
在这种情况下,当一个线程等待IO完成时,它将释放GIL,而另一个线程可以继续执行。
严格来说,CPython 支持多 io-bound-thread + single-cpu-bound-thread。
I/O绑定方法:file.open、、、、、等。当Python调用这些I/ file.writeO函数时,会释放GIL,并在I/O函数隐式返回后获取GIL 。file.readsocket.sendsocket.recv
CPU密集方法:算术计算等。
C 扩展方法:方法必须显式PyEval_SaveThread调用并告诉 Python 解释器您在做什么。PyEval_RestoreThread
| 归档时间: |
|
| 查看次数: |
1237 次 |
| 最近记录: |