python之GIL全局解释器锁,自定义互斥锁,死锁与递归锁

一.关于GIL与自定义互斥锁的区别

1.GIL是python解释器自带的锁,自定义互斥锁是我们程序里面自定义的锁

2.GIL锁只保证关于垃圾回收那一部分的数据是安全的,但是程序里面自定义的数据GIL无法保证,只能增加自定义锁

代码如下:

1.有自定义互斥锁的情况

from threading  import Thread,Lock
import time,random

n=100
mutex=Lock()

def task():
    global n
    with mutex:

        temp=n
        time.sleep(0.1)
        n=temp-1



if __name__ == '__main__':
    l=[]
    for i in range(100):
        t=Thread(target=task)
        l.append(t)
        t.start()
    for t in l:
        t.join()

    print(n) #0

2.只有GIL锁,没有自定义互斥锁的情况

from threading  import Thread,Lock
import time,random

n=100
# mutex=Lock()

def task():
    global n
    # with mutex:

    temp=n
    time.sleep(0.1)
    n=temp-1



if __name__ == '__main__':
    l=[]
    for i in range(100):
        t=Thread(target=task)
        l.append(t)
        t.start()
    for t in l:
        t.join()

    print(n)  #99

二.死锁与递归锁

当自定义锁运用的不得当,会造成死锁,死锁的解决方案是递归锁   自定义锁只能aquire一次  而递归锁可以aquire多次

from threading import Thread,Lock,RLock
import time

mutexA=Lock()
mutexB=Lock()
#mutexB=mutexA=RLock()


class Mythead(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 抢到A锁' %self.name)  
        mutexB.acquire()
        print('%s 抢到B锁' %self.name)  
        mutexB.release()
        mutexA.release()

    def f2(self):
        mutexB.acquire() 
        print('%s 抢到了B锁' %self.name) 
        time.sleep(2)
        mutexA.acquire()
        print('%s 抢到了A锁' %self.name)
        mutexA.release()
        mutexB.release()

if __name__ == '__main__':
    for i in range(100):
        t=Mythead()
        t.start()

 打印结果:

递归锁可以被一个线程aquire多次,每aquire一次计数加一,导致其它线程无法aquire这把锁(只有计数为零才可以被aquire)

from threading import Thread,Lock,RLock
import time

# mutexA=Lock()
# mutexB=Lock()
mutexB=mutexA=RLock()


class Mythead(Thread):
    def run(self):
        self.f1()
        self.f2()

    def f1(self):
        mutexA.acquire()
        print('%s 抢到A锁' %self.name)  ..1  ..2
        mutexB.acquire()
        print('%s 抢到B锁' %self.name)  ..1
        mutexB.release()
        mutexA.release()

    def f2(self):
        mutexB.acquire() ..1
        print('%s 抢到了B锁' %self.name) ..1
        time.sleep(2)
        mutexA.acquire()
        print('%s 抢到了A锁' %self.name)
        mutexA.release()
        mutexB.release()

if __name__ == '__main__':
    for i in range(100):
        t=Mythead()
        t.start()

打印结果:

三.信号量

信号量本质也是一把锁,但是与互斥锁不一样的是,信号量是有多把锁,能保证同一时刻多个线程同时运行

 

四.event事件

多个线程之间需要协同工作,一个线程的运行依赖另一个线程为它做好准备工作

from threading import Thread,Event
import time,random


event=Event()


def light():
    print("红灯正亮")
    time.sleep(random.randint(1,3))
    event.set() #绿灯亮 控制一个信号,

def car(name):
    print("%s正在等绿灯" %name)
    event.wait() #等绿灯 等待一个信号
    print("%s通行" %name)

if __name__ == '__main__':
    t1=Thread(target=light)
    t1.start()
    for i in range(10):
        t=Thread(target=car,args=("车辆%s" %i ,))
        t.start()

五.线程Queue

import queue


q=queue.Queue()  #先进先出
q.put(1)
q.put(2)
q.put(3)

print(q.get()) #1
print(q.get()) #2
print(q.get()) #3


q=queue.LifoQueue()  #后进先出
q.put(10)
q.put(20)
q.put(30)
print(q.get()) #30
print(q.get()) #20
print(q.get()) #10


q=queue.PriorityQueue()  #元组里面第一个参数越小 优先级越高
q.put((100,"a"))
q.put((0,"b"))
q.put((-1,"c"))
print(q.get()) #c
print(q.get()) #b
print(q.get()) #a

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值