马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 MSK 于 2017-6-7 17:05 编辑
内容概述
同步锁与递归锁,只允许一个线程访问公共资源
上一篇:
主线程堵塞
下一篇:
高级锁
当子线程启动时,全部线程一起执行,抢占CPU资源,有时如果大量线程同时访问一个函数,或者变量,就会出现问题。
比如:import time
import threading
def addNum():
global num #在每个线程中都获取这个全局变量
# num-=1
temp=num
print('--get num:',num )
#time.sleep(0.1)
num =temp-1 #对此公共变量进行-1操作
num = 100 #设定一个共享变量
thread_list = []
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list: #等待所有线程执行完毕
t.join()
print('最终的数字是 :', num )
我们把这个程序执行两次:
结果为:#C:\Users\Administrator\Desktop\课件\4>python 1.py
#--get num: 100
#--get num: 99
#--get num: 98
#--get num: 97
#--get num: 96
#省略。。。
#--get num: 5
#--get num: 4
#final num: 3
#C:\Users\Administrator\Desktop\课件\4>python 1.py
#--get num: 100
#--get num: 99
#--get num: 98
#--get num: 97
#--get num: 96
#--get num: 95
#省略。。。
#--get num: 7
#--get num: 6
#--get num: 5
#final num: 4
#C:\Users\Administrator\Desktop\课件\4>
用num -= 1则最终结果没问题,这是因为完成这个操作太快了,在线程切换时间内。用中间变量temp进行赋值时出现问题,这是因为100个线程,每一个都没有执行完就就行了切换,因此最终得到的不是0
多个线程同时操作同一个共享资源,所以导致冲突,这种情况就需要用同步锁来解决
创建锁的方法
#实例化一个锁对象
lock = threading.Lock()
#开启锁
lock.acquire()
#解除锁
lock.release()
锁保证了在调用lock.acquire()后,同一时间内只有“获得锁”的线程(先调用了lock.acquire()的线程)可以访问公共资源,其他线程被挂起,直到一个线程执行到lock.release()时解除锁,线程全部解放,下一个线程获得锁,访问公共资源,其他线程挂起。以此类推。
所以代码这样改就没问题了:import time
import threading
def addNum():
global num #在每个线程中都获取这个全局变量
# num-=1
lock.acquire()#加同步锁
temp=num
print('--get num:',num )
#time.sleep(0.1)
num =temp-1 #对此公共变量进行-1操作
lock.release()#解锁
num = 100 #设定一个共享变量
thread_list = []
lock=threading.Lock()#创建lock对象
for i in range(10):
t = threading.Thread(target=addNum)
t.start()
thread_list.append(t)
for t in thread_list:#等待所有线程执行完毕
t.join()#所有线程执行完后主程序才能结束
print('最终的数字是 :', num )
除了Lock,threading模块还提供了一种锁RLock(递归锁)
创建和使用方法差不多lock = threading.Lock()
rlock = threading.RLock()
lock.acquire()
#do something
lock.release()
rlock.acquire()
#do something
rlock.release()
Lock 与 RLock区别
|