|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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区别
|
-
评分
-
查看全部评分
|