Python 多线程

GIL

由于 GIL(Global Interpreter Lock)的存在,导致 Python 进程中最多同时运行一个线程,使得 Python 多线程是鸡肋般的存在。要想利用多核系统,Python必须支持多线程运行。与编译型语言不同,Python 是解释型语言,解释器要留意的是避免在不同的线程操作内部共享的数据,这就引出了 GIL。任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行。但是这并不代表不能使用 Python 多线程,对所有面向I/O的(会调用内建的操作系统C代码的)程序来说,GIL会在这个I/O调用之前被释放,以允许其他线程在这个线程等待I/O的时候运行。如果某线程并未使用很多I/O操作,它会在自己的时间片内一直占用处理器和GIL。也就是说,I/O密集型的Python程序比计算密集型的Python程序更能充分利用多线程的好处。

什么是计算密集型?什么是IO密集型?

计算密集型任务的特点是要进行大量的计算,消耗 CPU 资源,如计算圆周率,视频的编解码等。这种计算密集型任务也可以使用多任务完成,但是任务越多,花费在任务切换的时间就越多,CPU 的执行效率就越低。所以,要想高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

I/O密集型,涉及到网络、磁盘 I/O 的任务都是 I/O 密集型任务,这类任务的特点是 CPU 消耗很少,任务的大部分时间都在等待 I/O 操作完成(因为 I/O 的速度远远低于 CPU 和内存的速度)。对于 I/O 密集型任务,任务越多,CPU效率越高,但也有一个限度。I/O 密集型任务执行期间,99%的时间都花在 I/O 上,花在CPU上的时间很少,因此,在等待 I/O 的期间,Python 的 GIL 会被释放,允许其他线程使用 CPU。

Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

参考资料

赞赏是对作者最大的支持!
0%