GIL全局解释器锁

GIL全局解释器锁

Global Interpreter Lock

全局解释器

锁就是为了避免资源竞争造成数据的错乱

为什么解释器要加锁

1.启动解释器进程  python.exe

2.解析你的py文件并执行它

每个py程序中都必须有解释器参与,解释器其实就是一堆代码,相当多线程要调用同一个解释代码,共享就是竞争。竞争就要出事,所以需要要给解释器加上解释器。

python中内存管理依赖于GC(一段用于回收内存的代码)也是一个线程。除了你自己开的线程,系统还有一些内置线程。就算你的代码不会竞争解释器,内置线程也可能会竞争,所以必须加上锁。

GIL解锁的情况

当一个线程遇到了IO操作,同时解释器也会自动解锁,去执行其他线程CPU会切换到其他程序。

GIL性能的讨论

解释器加锁以后:

  将导致所有线程只能开发,不能达到真正的并行,意味着同一时间只有一个cpu在处理你的线程所以给你的感觉是效率低。

代码执行有两种状态

阻塞IO 失去cpu的执行权(cpu 等待IO完成)

非阻塞 代码正常执行,比如循环一千万次,中途cpu可能切换,很快就会回来(cpu在计算)

案例:假如有32核心cpu要处理一个下载任务,网络速度100k/s,文件大小1024kb。

  如果你的代码中IO操作非常多,cpu性能不能直接绝对决定你的任务处理速度。

对io密集程序和计算密集程序(多线程和多进程效率的差别)

IO密集程序

import time ,os
from multiprocessing import Process
from threading import Thread,current_thread

def task():
    time.sleep(3)


def task1():
    time.sleep(3)

def task2():
    time.sleep(3)


def task3():
    time.sleep(3)

def task4():
    time.sleep(3)


def task5():
    time.sleep(3)

if __name__ == '__main__':
    start = time.time()
    #多进程处理io密集程序 耗时3.6272077560424805
    # p = Process(target=task)
    # p1 = Process(target=task1)
    # p2 = Process(target=task2)
    # p3 = Process(target=task3)
    # p4 = Process(target=task4)
    # p5 = Process(target=task5)
    
    #多线程处理io密集程序 耗时3.001171588897705(3秒是io固定长度)
    p = Thread(target=task)
    p1 = Thread(target=task1)
    p2 = Thread(target=task2)
    p3 = Thread(target=task3)
    p4 = Thread(target=task4)
    p5 = Thread(target=task5)

    p.start()
    p1.start()
    p2.start()
    p3.start()
    p4.start()
    p5.start()

    p.join()
    p1.join()
    p2.join()
    p3.join()
    p4.join()
    p5.join()

    print(time.time()-start)

计算密集型程序

from multiprocessing import Process
from threading import Thread
import time
def task1():
    sum = 0
    for i in range(10000000):
        sum += i


def task2():
    sum = 0
    for i in range(10000000):
        sum += i

def task3():
    sum = 0
    for i in range(10000000):
        sum += i

def task4():
    sum = 0
    for i in range(10000000):
        sum += i

def task5():
    sum = 0
    for i in range(10000000):
        sum += i


if __name__ == '__main__':
    #多进程处理运算密集型程序 2.9081664085388184
    start = time.time()
    # t1 = Process(target=task1)
    # t2 = Process(target=task2)
    # t3 = Process(target=task3)
    # t4 = Process(target=task4)
    # t5 = Process(target=task5)

    #多线程处理运算密集型程序 4.190239667892456
    t1 = Thread(target=task1)
    t2 = Thread(target=task2)
    t3 = Thread(target=task3)
    t4 = Thread(target=task4)
    t5 = Thread(target=task5)


    t1.start()
    t2.start()
    t3.start()
    t4.start()
    t5.start()

    t1.join()
    t2.join()
    t3.join()
    t4.join()
    t5.join()

    print(time.time()-start)

可以得出结论

在计算密集程序中使用多进程处理效率更高

在io操作密集的程序中使用多线程处理效率更加高

原文地址:https://www.cnblogs.com/msj513/p/9947333.html