python多线程锁,python线程锁和全局锁
本文主要介绍Python并行编程多线程锁机制Lock和RLock实现线程同步。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。
00-1010什么是锁定机制?Lock()管理线程RLock()和Lock()之间的差异
目录
要回答这个问题,我们需要知道为什么需要使用锁机制。我们前面提到一个进程中多个线程的一些资源是共享的,这也是线程的一个很大的优势,但是这也带来了一个问题,就是当两个或者更多的线程同时访问共享资源的时候,如果这个时候没有预设相应的同步机制,可能会导致多个线程同时访问同一个共享资源,也就是race状态。大多数情况下,我们都不希望出现这种情况,那么如何避免呢?
什么是锁机制?
先看一段代码:
导入线程
导入时间
资源=0
计数=1000000
resource_lock=线程。锁定()
定义增量():
全球资源
对于范围内的I(计数):
资源=1
定义决定():
全球资源
对于范围内的I(计数):
资源-=1
增量_线程=线程。线程(目标=增量)
decerment _ thread=线程。线程(target=decerment)
increment_thread.start()
decerment _ thread.start()
increment_thread.join()
decerment _ thread.join()
打印(资源)
运行截图如下:
运行结果
当我们多次运行时,可以看到最终结果几乎不等于我们的期望值,也就是资源0的初始值。
为什么?原因是=和-=不是原子操作。
您可以使用dis模块来查看字节码:
进口dis
定义添加(总计):
总计=1
def desc(总计):
总计-=1
总计=0
打印(dis.dis(add))
印刷品(desc)
#运行结果:
# 3 0 LOAD_FAST 0(总计)
# 3负载常数1 (1)
# 6原地添加
# 7 STORE_FAST 0(合计)
# 10 LOAD_CONST 0(无)
# 13返回值
#无
# 5 0 LOAD_FAST 0(总计)
# 3负载常数1 (1)
# 6原地_减去
# 7 STORE_FAST 0(合计)
# 10 LOAD_CONST 0(无)
# 13返回值
#无
那么如何保证初始值为0呢?我们可以通过下面的代码使用Lock()。
导入线程
导入时间
资源=0
计数=1000000
resource_lock=线程。锁定()
定义增量():
全球资源
对于范围内的I(计数):
资源
e_lock.acquire()
resource += 1
resource_lock.release()
def decerment():
global resource
for i in range(count):
resource_lock.acquire()
resource -= 1
resource_lock.release()
increment_thread = threading.Thread(target=increment)
decerment_thread = threading.Thread(target=decerment)
increment_thread.start()
decerment_thread.start()
increment_thread.join()
decerment_thread.join()
print(resource)
运行截图如下:
运行结果
从运行结果可以看到,不论我们运行多少次改代码,其resource
的值都为初始值0
, 这就是Lock()
的功劳,即它可以将某一时刻的访问限定在单个线程或者单个类型的线程上,在访问锁定的共享资源时,必须要现获取对应的锁才能访问,即要等待其他线程释放资源,即resource_lock.release()
当然为了防止我们对某个资源锁定后,忘记释放锁,导致死锁,我们可以利用上下文管理器管理锁实现同样的效果:
import threadingimport time
resource = 0
count = 1000000
resource_lock = threading.Lock()
def increment():
global resource
for i in range(count):
with resource_lock:
resource += 1
def decerment():
global resource
for i in range(count):
with resource_lock:
resource -= 1
increment_thread = threading.Thread(target=increment)
decerment_thread = threading.Thread(target=decerment)
increment_thread.start()
decerment_thread.start()
RLock() 与Lock()的区别
我们需要知道Lock()
作为一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取,否则会发生死锁:
import threadingresource.lock = threading.lock()
resource = 0
resource.lock.acquire()
resource.lock.acquire()
resource += 1
resource.lock.release()
resource.lock.release()
为解决同一线程中不能多次请求同一资源的问题,python提供了可重入锁:threading.RLock
,RLock
内部维护着一个Lock
和一个counter
变量,counter
记录了acquire
的次数,从而使得资源可以被多次acquire
。
直到一个线程所有的acquire
都被release
,其他的线程才能获得资源 。用法和threading.Lock
类相同,即比如递归锁的使用:
import threadinglock = threading.RLock()
def dosomething(lock):
lock.acquire()
# do something
lock.release()
lock.acquire()
dosomething(lock)
lock.release()
以上就是Python并行编程多线程锁机制Lock与RLock实现线程同步的详细内容,更多关于Python锁Lock RLock线程同步的资料请关注盛行IT软件开发工作室其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。