GIL全局解释器锁

# 官方文档对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.

"""
1.在CPython解释器中存在全局解释器锁简称GIL
	python解释器有很多类型
	CPython JPython PYPython(常见的是CPython解释器)
2.GIL本质也是一把互斥锁,用来阻止同一个进程内多个线程同时执行(重要)
3.GIL的存在是因为CPython解释器中内存管理不是线程安全的(垃圾回收机制)
	垃圾回收机制:
	引用计数、标记清楚、分代回收
"""

验证GIL的存在

from threading import Thread

num = 100


def task():
    global num
    num -= 1


t_list = []  # 定义一个列表
for i in range(100):
    t = Thread(target=task)
    t.start()  # 创建子进程
    t_list.append(t)  # 子进程添加列表里面
for t in t_list:
    t.join()  # 主进程等子进程结束才执行,这样全部子进程结束才会打印num
print(num)

image

死锁现象

from threading import Thread, Lock
import time

mutexA = Lock()  # 产生一把锁A
mutexB = Lock()  # 产生一把锁B


class MyThreading(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        mutexA.acquire()
        print(f'{self.name}抢到了A锁')
        mutexB.acquire()
        print(f'{self.name}抢到了B锁')
        mutexB.release()
        print(f'{self.name}释放了B锁')
        mutexA.release()
        print(f'{self.name}释放了A锁')

    def func2(self):
        mutexB.acquire()
        print(f'{self.name}抢到了B锁')
        time.sleep(1)
        mutexA.acquire()
        print(f'{self.name}抢到了A锁')
        mutexA.release()
        print(f'{self.name}释放了A锁')
        mutexB.release()
        print(f'{self.name}释放了B锁')


for i in range(10):
    obj = MyThreading()
    obj.start()
"""
死锁产生原因:
多个线程同时产生,去抢锁A,这时只有一个线程抢到了锁A,其他线程需要排队,抢到锁A的线程才可以去抢锁B,这时候没有其他线程可以参与抢锁A与锁B,因为锁A还没有被释放,抢到了锁B的线程释放了锁B,但是其他线程因为锁A没有释放不能够抢,线程1执行函数func2,抢锁B,因为刚才锁B已经被释放,其他线程则其实有一个抢到了锁A,线程1碰到IO操作,CPU切换,抢到了锁A的执行但是下一步要抢锁B,而锁B在线程1手上,无法继续下一步,等线程1O操作,他要抢锁A,而锁A在其他线程手中也无法继续下一步,这时候就会产生死锁现象
"""

image

信号量

在python并发编程中信号量相当于多把互斥锁

from threading import Thread, Semaphore
import time
import random

sp = Semaphore(5)  # 一次性产生5把锁

class Mythread(Thread):
    def run(self):
        sp.acquire()   # 加锁
        print(self.name)
        time.sleep(random.randint(1,3))  # 模拟延迟
        sp.release()   # 释放锁

for i in range(20):
    t = Mythread()
    t.start()
"""
信号量可以理解问,我们同时产生5把锁让线程去抢,这时候就会有5个线程去抢到5把锁,然后去执行,有线程执行完毕把锁的位置让出来其他线程去抢到空余的锁执行
"""

event事件

from threading import Thread, Event
import time

event = Event()  # 类似造了一个红绿灯


def light():
    print('红灯亮着 所有人不能动')
    time.sleep(3)
    print('绿灯亮了 油门踩到底!冲冲冲!!!')
    event.set()


def car(name):
    print(f'{name}正在等红灯')
    event.wait()  # event事件表示,会在这里等待执行到event.set()执行结束才会执行
    print(f'{name}飙车了')


t = Thread(target=light)
t.start()
for i in range(10):
    t = Thread(target=car, args=('熊猫PRO%s' % i,))
    t.start()
"""
event是一个组合使用的,在执行过程中到event.wait()这里会停止,等待程序执行event.set()执行以后才会执行后面的
"""
posted @ 2022-11-21 20:30  雪语  阅读(35)  评论(0编辑  收藏  举报