Python--GIL锁

一、进程与线程

1.进程

操作系统进行资源分配和调度的基本单位,多个进程之间相互独立。

2.线程

CPU进行资源分配和调度的基本单位,线程是进程的一部分,是比进程更小的能独立运行的基本单位,一个进程下的多个线程可以共享进程的多个资源。

二、GIL锁

1、GIL定义

全局解释器锁,简单来说是一个互斥锁,每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。

2、GIL的准则

1)当前执行线程必须持有GIL

2)当线程遇到 IO的时、时间片到时或遇到阻塞时, 会释放GIL(Python 3.x使用计时器----执行时间达到阈值后,当前线程释放GIL,或Python 2.x,tickets计数达到100。)

三、多线层不能充分利用多核GPU的优势

1、CPU密集采用多进程,假如IO操作少,用多线程的话,因为线程共享一个全局解释器锁,当前运行的线程会霸占GIL,其他线程没有GIL,就不能充分利用多核CPU的优势。

计算密集型--采用多进程(耗时2秒左右)

from multiprocessing import Process
import time
from threading import Thread

def foo():
    res = 1.1
    for i in range(1, 100000000):
        res *= i

if __name__ == '__main__':
    l = []
    start_time = time.time()
    for i in range(8):
        p = Process(target=foo)
        p.start()  # 启动进程,并调用该子进程中的p.run(),p.run()调用target指定的函数
        l.append(p)
    for p in l:
        p.join()  # 主进程等待所有子进程p执行完毕,才执行

    print(time.time() - start_time)

计算密集型--采用多线程(耗时37秒) 

from multiprocessing import Process
import time
from threading import Thread
def foo():
    res = 1.1
    for i in range(1, 100000000):
        res *= i

if __name__ == '__main__':
    l = []
    start_time = time.time()
    for i in range(8):
        p = Thread(target=foo)
        p.start()
        l.append(p)
    for p in l:
        p.join()

    print(time.time() - start_time)

2、IO操作密集采用多线程,在用户输入,sleep的时候,可以切换到其他线程执行,减少等待时间。常见IO密集型任务:网络IO(抓取网页数据)、磁盘操作(读写文件)、键盘输入。

IO密集型--采用多进程(耗时19秒)

def foo():
    time.sleep(2)  # IO操作时会释放CPU -- CPU大多数时间是处于闲置状态,频繁的切换

if __name__ == '__main__':
    l = []
    start_time = time.time()
    for i in range(1000):
        p = Process(target=foo)
        p.start()
        l.append(p)
    for p in l:
        p.join()

    print(time.time() - start_time)

 IO密集型--采用多线程(耗时2秒) 

def foo():
    time.sleep(2)

if __name__ == '__main__':
    l = []
    start_time = time.time()
    for i in range(1000):
        p = Thread(target=foo)
        p.start()
        l.append(p)
    for p in l:
        p.join()

    print(time.time() - start_time)

四、总结

1、对于IO密集型应用,即使有GIL存在,由于IO操作会导致GIL释放,其他线程能够获得执行权限。由于多线程的通讯成本低于多进程,因此偏向于使用多线程。

2、对于计算密集型应用,由于CPU一直处于被占用,GIL锁直到规定时间才会释放,然后才会切换状态,导致多线程处于绝对的劣势,此时可以采用多进程+协程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值