python高级语法——(1)GIL学习

本文介绍了Python中的全局解析器锁(GIL),它确保同一时刻只有一个线程执行代码,导致多线程在CPU密集型任务中无法充分利用多核。在IO密集型任务中,GIL会在阻塞时释放,允许其他线程并发执行。为解决GIL问题,可以使用多进程或用C语言编写多线程任务,并在Python中导入。
摘要由CSDN通过智能技术生成

GIL(全局解析器锁)

GIL,全局解析器锁,只对多线程有影响。
如果没有GIL,多线程会同时调用全局资源,全局资源会因多个线程同时调用而造成数据错误。
因此每个线程在执行过程中都需要先获取GIL,保证同一时刻只有一个线程在执行代码,这样才不会造成数据错误。

多线程并不是真正“多线程”的例子
  • 单进程下的CPU利用率
    下面代码保存为single_thread.py,同时运行两个single_thread.py,两个程序各占满两个CPU核心,CPU利用率为100%。
# 主进程死循环,占用整个CPU
def single_thread():
    while True:
        pass

test()
  • 多线程下的CPU利用率
    下面代码保存为multithreading.py ,运行后发现,单进程内双线程即使同时死循环,两个核心中的CPU资源利用率都仅为50%。可以认为实际上只有一个核占满资源,和单线程没区别。
import threading


# 子进程死循环
def test_thread1():
    while True:
        pass


t1 = threading.Thread(target=test_thread1)
t1.start()


# 主进程死循环
def test_thread2():
    while True:
        pass


test_thread2()
  • 多进程下的CPU利用率
    下面代码保存为multiprocessing.py,运行后发现CPU中两个核心的资源利用率为100%。
import multiprocessing


# 子进程
def test_multiprocessing1():
    while True:
        pass


m1 = multiprocessing.Process(target=test_multiprocessing1)
m1.start()


# 主进程
def test_multiprocessing2():
    while True:
        pass


test_multiprocessing2()

总结:多线程在死循环的程序中也不会导致CPU满资源的原因是GIL。全局解析器锁GIL的存在会限制多线程在运行中,实际仅有一个线程在执行任务。

  • GIL不是python语言的问题,是python解析器的问题,cpython(C语言写的解析器)中存在这样的问题;
  • 因此如果用的是cpython解析器,想要发挥多核性能,应该使用多进程;如果是其他解析器,多线程也能发挥多核性能;
  • 爬虫程序中,多线程比单线程性能用提升,因为在遇到IO阻塞会自动释放GIL锁。
计算密集型程序和IO密集型程序
  • 计算密集型
    计算密集型程序,多用于计算和分析等领域的程序,GIL在这种程序中是个累赘,多线程等于单线程;

    多进程没GIL的影响,因此多进程适合计算密集型程序

  • IO密集型
    IO,input和output输入输出类型,程序中常出现阻塞,计时等需要耗时的情况,GIL能在线程阻塞时自动释放GIL锁,其他线程就能执行代码,形成多线程并发的假象;

总结:多线程适用于IO密集型程序

用C语言解决GIL锁问题

多线程任务用C语言编写,通过在python代码中导入C语言文件解决多线程中GIL的问题

  • 下面代码保存为deadloop.c文件
void DeadLoop(){
    while(1){
        ;
    }
}
  • 通过gcc 文件名.c -shared -o lib文件名.so编译后得到libdeadloop.so动态库文件
  • 将下面代码保存为solution.py文件,文件中加载了libdeadloop.so动态库中的DeadLoop()函数作为子线程
from ctypes import *
import threading

# 加载动态库libdeadloop
lib = cdll.LoadLibrary("./libdeadloop.so")

# 创建一个子线程,加载动态库中的DeadLoop()函数,此函数是一个死循环
t = threading.Thread(target=lib.DeadLoop)
t.start()


# 主线程
def multi_threading2():
    while True:
        pass


multi_threading2()

总结:此时运行solution.py文件,多线程中为两个死循环,占用的CPU资源比为100%,证明解决了GIL锁线程的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值