并发编程(3)----线程锁

1.问什么要用线程锁?

因为并发的存在我们不能保证线程内的某段代码执行完毕之后再去执行其他代码,而且对于线程共享的数据我们不能确保他的安全,所以我们通过加线程锁(给代码加锁)来保证线程安全。

2.线程锁应用场景?

IO密集型操作

3.线程锁的分类?

①Lock 同步锁 缺点:不支持多次加锁和解锁,会造成死锁现象
②Rlock 递归锁 用的最多
③BoundedSemaphore(n) 信号量 在创建锁的时候规定好一次能通过几个线程
④Condition() 条件锁
lock.notify(n) 动态的,用户指定个数
lock.wait_for(条件) 当条件满足时就解锁
⑤Event() 红绿灯
lock.wait() 红灯,线程阻塞
lock.set() 绿灯,线程继续执行
lock.clear() 变回红灯,线程阻塞

4.线程锁和GIL的区别?

看图:
在这里插入图片描述
线程锁是在线程层面上,GIL全局解释器大锁,就算线程过了线程锁,还是要受GIL大锁的约束

6.代码展示

1.Lock

import threading
import time

lock = threading.Lock()
def test(arg):
    #这样写的话程序会阻塞,因为Lock不支持多次加锁和解锁,会造成死锁
    lock.acquire()
    time.sleep(0.5)
    lock.acquire()
    print(arg)
    lock.release()
    lock.release()
    
for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

2.Rlock

import threading
import time

lock = threading.RLock()
lock1 = threading.Lock()
def test(arg):
    #Rlock支持多次加锁和解锁,不会造成死锁
    lock.acquire()
    time.sleep(0.5)
    lock.acquire()
    print(arg)
    lock.release()
    lock.release()


for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

ps:加锁之后一定要解锁,否则程序会阻塞

3.BoundedSemaphore(n)

import threading
import time

lock = threading.BoundedSemaphore(3)

def test(arg):
    lock.acquire()
    print(arg)
    time.sleep(1)
    lock.release()

for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

4.Condition()

import threading
import time
lock = threading.Condition()

###方法1
def test(arg):
    lock.acquire()
    lock.wait()
    print(arg)
    time.sleep(1)
    lock.release()

for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

while True:
    ina = input(">>")
    lock.acquire()
    lock.notify(int(ina))   #根据用户输入来决定要解锁的线程数
    lock.release()

###方法2
def operation():
    user = input(">>")
    td = threading.current_thread()
    print(td.getName())
    return True

def test(arg):
    print("线程进来了")
    lock.acquire()
    lock.wait_for(operation)  #wair_for跟一个条件,等条件执行完毕之后继续往下走
    print(arg)
    time.sleep(1)
    lock.release()

for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

5.Event()

import threading
import time
lock = threading.Event()
def test(arg):
    print("线程进来了")
    lock.wait()
    print(arg)

for i in range(10):
    t = threading.Thread(target=test,args=(i,))
    t.start()

input(">>")
lock.set()  #变绿灯,线程可以继续往下回字形

lock.clear() #变为红灯
for i in range(10):  #如果不是值lock.clear(),程序也会执行,因为上边已经将灯变为绿灯了
    r = threading.Thread(target=test,args=(i,))
    r.start()
input(">>")
lock.set()   #变绿灯,线程继续执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值