全局解释器和线程

[TOC]

1.全局解释器锁

1.1python解释器:

​ -Cpython c语言

​ -Jpython java

1.2GIL :全局解释器

​ -翻译:在同一个进程下开启的多线程,同一时刻只能有有一个线程执行,因为cpython的内存管理不是线程安全。

​ -GIL全局解释器,本质上是一把互斥锁,保证数据安全

​ 在Cpython解释器中,同一个进程下开启多个线程,同一时刻只能有一个线程执行,无法利用多核优势。

​ -为什么要有全局解释器锁:

​ -没有锁

​ -GIL全局解释器锁的优点:

​ -优点:

​ 保证数据的安全

​ -缺点:

​ 单个进程下,开启多个线程,牺牲执行效率了,无法实现并行,只能实现并发。

​ -IO密集型: 多线程

​ -计算机密集型:多进程

import time
from threading import Thread
n = 100
def task():
    global n
    m = n
    time.sleep(3)
    n =m -1####实际产生了10个99  最后一个只打印了一个n
    
    #print(n)

if __name__ == '__main__':
    list = []
    for line in range(10):
        t = Thread(target = task)
        t.start()
        list.append(t)

    for t in list:
        t.join()
    print(n)
    >>>>>>>>>>>>>>>>>>>>>>
    99

2.协程

-定义:

​ -进程:资源单位

​ -线程:执行单位

​ -协程:单线程西实现并发

​ -在IO密集的情况下,使用协程能提高最高效率

注意:协程不是任何单位,使用协程能提高最高效率

协程的目的:

​ -手动实现“遇到IO切换+保存状态” ,因为是在单线程下,控制单线程的多个任务在一个任务遇到io,就切换到另外一个任务执行,这样保证了,线程能够最大限度的处于就绪化,即随时都可以被cpu执行的状态,可以去欺骗操作系统,让操作系统误以为没有io操作,从而将cpu的执行权限交给你。

​ -必须只有单线程实现并发,

​ -协程指的是单个线程,一旦线程出现阻塞,及那个会阻塞整个线程

from gevent import monkey  # 猴子补丁   
monkey.patch_all()  # 监听所有的任务是否有IO操作 
#上面的2个必须写在文件的开头,在time socket的模块之前,这样形成的io 可以直接识别
from gevent import spawn  # spawn(任务)  spawn(函数名,参数,参数)
from gevent import joinall
import time

def task1():
    print('start from task1...')
    time.sleep(1)
    print('end from task1...')

def task2():
    print('start from task2...')
    time.sleep(3)
    print('end from task2...')

def task3():
    print('start from task3...')
    time.sleep(5)
    print('end from task3...')


if __name__ == '__main__':

    start_time = time.time()
    sp1 = spawn(task1)
    sp2 = spawn(task2)
    sp3 = spawn(task3)
    # sp1.start()
    # sp2.start()
    # sp3.start()
    # sp1.join()
    # sp2.join()
    # sp3.join()
    joinall([sp1, sp2, sp3])

    end_time = time.time()

    print(f'消耗时间: {end_time - start_time}')
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start task1...
start task2...
start task3...
end task1...
end task2...
end task3...
消耗时间:3.0044186115264893

3.使用多线程提高效率

from threading import Thread
from multiprocessing import Process
import time

#计算密集型任务
def task1():
    i = 10
    for line in range(1000000):
        i += 1

#io密集型任务
def task2():
    time.sleep(3)

if __name__ == '__main__':
    #测试多进程
    #计算密集型
    a = time.time()
    list1 = []
    for line in range(6):
        p = Process(target = task1)
        print(p)
        p.start()
        list1.append(p)

    for p in list1:
        p.join()
    b = time.time()
    print(f'计算进程密集型消耗的时间:{b-a}')

    #测试IO密集型
    a = time.time()
    list2 = []
    for line in range(6):
        p = Process(target = task2)
        p.start()
        list2.append(p)

    for p in list2:
        p.join()
    b = time.time()
    print(f'IO进程密集型消耗时间:{b-a}')

    #2.测试多线程的
    #测试计算密集型
    a = time.time()
    list1 = []
    for line in range(6):
        p = Thread(target = task1)
        p.start()
        list1.append(p)

    for p in list1:
        p.join()
        b = time.time()
    print(f'计算线程密集型消耗时间:{b -a}')

    #测试IO密集型
    a = time.time()
    list1 = []
    for line in range(6):
        p = Thread(target = task2)
        p.start()
        list1.append(p)

    for p in list1:
        p.join()
    b = time.time()
    print(f'IO线程密集型的消耗时间:{b - a}')
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
计算进程密集型消耗的时间:0.3511178493499756
IO进程密集型消耗时间:3.215735912322998
计算线程密集型消耗时间:0.43486547470092773
IO线程密集型的消耗时间:3.003101110458374

猜你喜欢

转载自www.cnblogs.com/bs2019/p/12037237.html