欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈Python中的全局锁(GIL)问题

程序员文章站 2023-12-05 10:58:52
cpu-bound(计算密集型) 和i/o bound(i/o密集型) 计算密集型任务(cpu-bound) 的特点是要进行大量的计算,占据着主要的任务,消耗cpu资源,...

cpu-bound(计算密集型) 和i/o bound(i/o密集型)

计算密集型任务(cpu-bound) 的特点是要进行大量的计算,占据着主要的任务,消耗cpu资源,一直处于满负荷状态。比如复杂的加减乘除、计算圆周率、对视频进行高清解码等等,全靠cpu的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,cpu执行任务的效率就越低,所以,要最高效地利用cpu,计算密集型任务同时进行的数量应当等于cpu的核心数。

计算密集型任务由于主要消耗cpu资源,因此,代码运行效率至关重要。python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用c语言编写。

io密集型任务(i/o bound)的特点是指磁盘io、网络io占主要的任务,cpu消耗很少,任务的大部分时间都在等待io操作完成(因为io的速度远远低于cpu和内存的速度)。

io密集型任务执行期间,99%的时间都花在io上,花在cpu上的时间很少,因此,用运行速度极快的c语言替换用python这样运行速度极低的脚本语言,完全无法提升运行效率。

对于io密集型任务,任务越多,cpu效率越高,但也有一个限度。常见的大部分任务都是io密集型任务,比如请求网页、读写文件等。当然我们在python中可以利用sleep达到io密集型任务的目的。

对于io密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,c语言最差。

全局锁问题:

解释器被一个全局解释器锁保护着,它确保任何时候都只有一个python线程执行。

gil最大的问题就是python的多线程程序并不能利用多核cpu的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单cpu上面运行)。

gil只会影响到那些严重依赖cpu的程序(比如计算型的)

如果你的程序大部分只会设计到i/o,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。实际上,你完全可以放心的创建几千个python线程, 现代操作系统运行这么多线程没有任何压力,没啥可担心的。

解决方案:

首先,如果你完全工作于python环境中,你可以使用 multiprocessing 模块来创建一个进程池, 并像协同处理器一样的使用它。

pool = none

# performs a large calculation (cpu bound)
def some_work(args):
 ...
 return result

def some_thread():
 while true:
  ...
  r = pool.apply(some_work, (args))
  ...

# initiaze the pool
if __name__ == '__main__':
 import multiprocessing
 pool = multiprocessing.pool()

另外一个解决gil的策略是使用c扩展编程技术。 主要思想是将计算密集型任务转移给c,跟python独立,在工作的时候在c代码中释放gil。

以上这篇浅谈python中的全局锁(gil)问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。