python多线程之锁
摘要:本文主要介绍python线程中的几个锁,介绍其功能、实现的代码和结果截图,为了每一个锁能够独立理解,都贴出具体的测试代码(代码看上去很冗余,看完一个后,之后的只需看注释部分锁的创建部分,其他代码基本一样)。更多关于锁的详情点击链接:
python文档: link.
一、普通锁(互斥锁)
1、功能
- 线程之间资源争夺导致的死锁
- 数据的重复读取不一致问题
2、代码实现
import threading
import time
mylist = list(range(5))
####### 创建锁 (Lock、RLock)#########
lock = threading.RLock()
def task():
t = threading.current_thread()
name = t.name
tid = t.ident
########## 获取锁 ########
with lock:
mylist.pop(0)
print(f'{name}-{tid} running: current num=>{mylist}')
time.sleep(1)
print(f'{name}-{tid} result: current num=>{mylist}')
# 两个打印的输出是否一致
def main():
print('app start')
for i in range(5):
# 创建了一个线程
t = threading.Thread(target=task)
# 启动线程
t.start()
print('app end')
if __name__=='__main__':
main()
3、运行结果(win10+pycharm)
二、信号锁
1、功能
- 指定最多同时运行线程的个数
2、代码实现
import threading
import time
mylist = list(range(5))
############### 创建锁 (Semaphore),允许通过2个线程 #######
lock = threading.Semaphore(2)
def task():
t = threading.current_thread()
name = t.name
tid = t.ident
print(f'create {name}')
######### 获取锁 ##########
with lock:
mylist.pop(0)
print(f'{name}-{tid} running: current num=>{mylist}')
time.sleep(1)
print(f'{name}-{tid} result: current num=>{mylist}')
# 两个打印的输出是否一致
def main():
print('app start')
for i in range(5):
# 创建了一个线程
t = threading.Thread(target=task)
# 启动线程
t.start()
print('app end')
if __name__=='__main__':
main()
3、结果截图(Linux)
三、事件锁
1、功能
- 根据一个状态位,来决定线程是否通过运行(不能指定线程的个数)
2、代码实现
import threading
import time
mylist = list(range(5))
############# 创建锁 (Event) ##################
event = threading.Event()
############# 状态为设置为false ########
event.clear()
def task():
t = threading.current_thread()
name = t.name
tid = t.ident
print(f'create {name}')
########## 判断状态为是否为True #######
event.wait()
mylist.pop(0)
print(f'{name}-{tid} running: current num=>{mylist}')
time.sleep(1)
print(f'{name}-{tid} result: current num=>{mylist}')
# 两个打印的输出是否一致
def main():
print('app start')
for i in range(5):
# 创建了一个线程
t = threading.Thread(target=task)
# 启动线程
t.start()
######## 当状态位为false堵塞时,人为输入来改变状态位 #########
flag = input('>>>')
if flag == '1':
# 设置为True
event.set()
print('app end')
if __name__=='__main__':
main()
3、结果截图(Linux)
四、条件锁
1、功能
- 根据某些条件来决定线程是否通过运行(可以指定线程的个数)
2、代码实现
import threading
import time
mylist = list(range(5))
########### 创建锁 (Condition) ############
lock = threading.Condition()
def task():
t = threading.current_thread()
name = t.name
tid = t.ident
print(f'create {name}')
# 获取锁
with lock:
##### 判断条件是否为True ##########
lock.wait()
mylist.pop(0)
print(f'{name}-{tid} running: current num=>{mylist}')
time.sleep(1)
print(f'{name}-{tid} result: current num=>{mylist}')
# 两个打印的输出是否一致
def main():
print('app start')
thread_list = []
for i in range(5):
# 创建了一个线程
t = threading.Thread(target=task)
thread_list.append(t)
# 启动线程
t.start()
############# 人为输入设置线程通过得个数 ########
while thread_list:
n = int(input(">>>"))
with lock:
lock.notify(n)
for i in range(n):
thread_list.pop(0)
print('app end')
if __name__=='__main__':
main()
3、结果截图(Linux)
五、GIL锁
1、功能
GIL锁与python语言无关,是cpython解释器中的内容,保证同一时刻只运行一个线程。缺点:同一时刻只能用一个cpu
- 解决多线程之间数据共享时,数据错乱的问题。
2、运行流程
图片来源于网络,侵权删