Python并发编程之GIL解释器锁

1.什么是GIL全局解释器锁

'''
定义:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple 
native threads from executing Python bytecodes at once. This lock is necessary mainly 
because CPython's memory management is not thread-safe. (However, since the GIL 
exists, other features have grown to depend on the guarantees that it enforces.)
''' 
结论:在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

首先说明一下,我们程序里面向操作系统申请开进程和线程,其实是程序先调用python解释器功能(python程序是依赖解释器运行的),然后被python解释器解释为cpu可执行的代码。所以实际上是python解释器发起的请求。

然后再说明GIL解释器,从上面的这段GIL定义可知,GIL其实本质上是一个Cpython解释器自带的互斥锁(把多个任务对数据的修改由并发变成串行,虽然牺牲了效率,但保障了数据安全),相当于执行权限,每个进程内部都会存在一把GIL,同一进程内的多个线程必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行,但是可以实现并发

在cPython解释器下,如果想实现并行可以开启多个进程

2.为何要有GIL(因为Cpython解释器的垃圾回收机制不是线程安全的)

首先要知道Python多线程底层的实现原理

首先在一个进程里面有多个线程,这些线程中会包含python解释器自带的一个线程(垃圾回收线程),这些线程必须先拿到python解释器代码(可以理解成代码的执行权限),才可以由cpu来执行,假如这些线程是并行执行的,在线程1执行过程中产生的数据,恰好被垃圾回收线程清理,显然这是不合理的,数据的安全得不到保障,所以我们需要一把锁,保证这把锁同一时刻只能被一个线程执行,在线程1执行的过程中,其它线程是无法执行的,除非线程1释放这把锁,然后被其它线程使用。由此可以得出:一个进程下的多线程在GIL的情况下,可以实现并发,但是无法实现并行。(可以理解成多个人在厕所抢一个坑位)多个进程里面的线程可以实现并行

 

3.如何用GIL(有了GIL,应如何处理并发)

1.在单核的情况下,使用多线程的开销要小于多进程的开销

2.在多核的情况下,有4个任务,选用哪一种方案更合适:

  分情况讨论:当4个任务为计算密集型任务的时候,这个时候选多进程,因为多进程可以实现4个任务并行执行

                        当4个任务为IO密集型任务的时候,这个时候选多线程,多线程资源开销占用的少

下面用代码演示:

1.计算密集型:

def task():
     res=0
      for i in range(10000000):
           res+=i
    


if __name__ == '__main__':
    L=[]
    print(os.cpu_count())
    start=time.time()
    for i in range(4):
        p=Process(target=task) #2.10512    
        # p=Thread(target=task)  #3.4121   
        L.append(p)
        p.start()
    for p in L:
        p.join()
    stop=time.time()
    print("run time is %s" %(stop-start))

   2.IO密集型:

def task():
    
    time.sleep(5)


if __name__ == '__main__':
    L=[]
    print(os.cpu_count())
    start=time.time()
    for i in range(4):
        p=Process(target=task)    #5.31
        # p=Thread(target=task)    #5.00
        L.append(p)
        p.start()
    for p in L:
        p.join()
    stop=time.time()
    print("run time is %s" %(stop-start))

在python解释器下面,一个进程里面的多线程可以实现并发,因为有了GIL这把锁的存在为了解决垃圾回收数据不安全的问题,导致了同一进程下的多个线程不能实现并行

python解释器下面,一个进程里面的多个线程不能实现并行无法使用多核优势并不能说在python解释器中多线程没什么作用,多核带来的优势是计算性能的提升,当我们的python代码是多IO型的,这个时候多线程占优势,当我们的程序是多计算型的,这个时候多进程占优势,多核优势就显现出来了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值