python多线程锁,python线程锁和全局锁

  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 threading

  import 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 threading

  resource.lock = threading.lock()

  resource = 0

  resource.lock.acquire()

  resource.lock.acquire()

  resource += 1

  resource.lock.release()

  resource.lock.release()

  

  为解决同一线程中不能多次请求同一资源的问题,python提供了可重入锁:threading.RLockRLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次acquire

  直到一个线程所有的acquire都被release,其他的线程才能获得资源 。用法和threading.Lock类相同,即比如递归锁的使用:

  

import threading

  lock = 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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: