互斥锁、死锁、递归锁、信号量、GIL锁

互斥锁

互斥锁Lock也是一种阻塞,可以保证共享数据操作的完整性。保证在任一时刻,只能有一个线程访问该对象

from multiprocessing import Process
from threading import Thread
from multiprocessing import Lock # 进程锁
# from threading import Lock # 线程锁
import time
def a(lock):
    lock.acquire() # 加锁
    print("p1前")
    time.sleep(1)
    print("p1后")
    lock.release() # 解锁
def b(lock):
    lock.acquire() # 加锁
    print("p2前")
    time.sleep(1)
    print("p2后")
    lock.release() # 解锁
if __name__ == '__main__':
    lock = Lock() # 创建一个锁
    p1 = Process(target=a,args=(lock,))
    p2 = Process(target=b,args=(lock,))
    p1.start()
    p2.start()

死锁

是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程

from threading import Thread
from threading import Lock
import time
locka = Lock()
lockb = Lock()
class Te(Thread):
    def run(self):
        self.a()
        self.b()
    def a(self):
        locka.acquire()
        print(f"{self.name}拿到A锁")
        lockb.acquire()
        print(f"{self.name}拿到B锁")
        lockb.release()
        print(f"{self.name}释放B锁")
        locka.release()
        print(f"{self.name}释放A锁")
    def b(self):
        lockb.acquire()
        print(f"{self.name}拿到B锁")
        time.sleep(0.1)
        locka.acquire()
        print(f"{self.name}拿到A锁")
        locka.release()
        print(f"{self.name}释放A锁")
        lockb.release()
        print(f"{self.name}释放B锁")
if __name__ == '__main__':
    for i in range(3):
        t = Te()
        t.start()

递归锁

递归锁RLock可以解决死锁问题,递归锁有一个计数器,每次上锁都会加一,解锁会减一,直到计数器为零时其他进程才可以进行抢锁

from threading import Thread
from threading import RLock
import time
locka = lockb = RLock() # 创建格式
class Te(Thread):
    def run(self):
        self.a()
        self.b()
    def a(self):
        locka.acquire()
        print(f"{self.name}拿到A锁")
        lockb.acquire()
        print(f"{self.name}拿到B锁")
        lockb.release()
        print(f"{self.name}释放B锁")
        locka.release()
        print(f"{self.name}释放A锁")
    def b(self):
        lockb.acquire()
        print(f"{self.name}拿到B锁")
        time.sleep(0.1)
        locka.acquire()
        print(f"{self.name}拿到A锁")
        locka.release()
        print(f"{self.name}释放A锁")
        lockb.release()
        print(f"{self.name}释放B锁")
if __name__ == '__main__':
    for i in range(3):
        t = Te()
        t.start()

信号量

Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1;调用release() 时内置计数器+1;计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

from threading import Thread,Semaphore
import time
sem = Semaphore(2)
def a(name):
    sem.acquire()
    print(name)
    time.sleep(2)
    sem.release()
if __name__ == '__main__':
    for i in range(5):
        t = Thread(target=a,args=(f"线程{i}",))
        t.start()

GIL全局解释器锁

GIL锁是一个解释器级别的锁,保证了同一时刻只能一个线程进入解释器,jpyhon和pypy都没有GIL锁,保证了cpython解释器的数据资源安全的同时,也使单进程多线程的程序不能利用多核

GIL锁和lock锁的区别

  • 两种锁都是互斥锁,GIL锁保护解释器内部资源数据的安全,上锁和释放锁不需要手动操作
  • lock锁保护进程或线程中的资源数据安全,是自己定义的,需要自己手动上锁和释放锁
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值