资讯专栏INFORMATION COLUMN

python多线程死锁现象及解决方法

89542767 / 500人阅读

  小编写这篇文章的一个主要目的,主要是来给大家进行阐述关于python多线程的问题一些问题解答,包括遇到多线程问题现象,那么,遇到这种现象的话,我们需要怎么去进行解答呢?下面小编就给大家详细解答下。


  本节重点


  了解死锁现象与解决方法


  本节时长需控制在15分钟内


  一死锁现象


  所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。


  此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁


  from threading import Thread,Lock
  import time
  mutexA=Lock()
  mutexB=Lock()
  class MyThread(Thread):
  def run(self):
  self.func1()
  self.func2()
  def func1(self):
  mutexA.acquire()
  print('33[41m%s拿到A锁33[0m'%self.name)
  mutexB.acquire()
  print('33[42m%s拿到B锁33[0m'%self.name)
  mutexB.release()
  mutexA.release()
  def func2(self):
  mutexB.acquire()
  print('33[43m%s拿到B锁33[0m'%self.name)
  time.sleep(2)
  mutexA.acquire()
  print('33[44m%s拿到A锁33[0m'%self.name)
  mutexA.release()
  mutexB.release()
  if __name__=='__main__':
  for i in range(10):
  t=MyThread()
  t.start()


  执行效果


  Thread-1拿到A锁
  Thread-1拿到B锁
  Thread-1拿到B锁
  Thread-2拿到A锁#出现死锁,整个程序阻塞住


  二递归锁


  解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。


  这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。


  上面的例子如果使用RLock代替Lock,则不会发生死锁,二者的区别是:递归锁可以连续acquire多次,而互斥锁只能acquire一次


  from threading import Thread,RLock
  import time
  mutexA=mutexB=RLock()#一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止
  class MyThread(Thread):
  def run(self):
  self.func1()
  self.func2()
  def func1(self):
  mutexA.acquire()
  print('33[41m%s拿到A锁33[0m'%self.name)
  mutexB.acquire()
  print('33[42m%s拿到B锁33[0m'%self.name)
  mutexB.release()
  mutexA.release()
  def func2(self):
  mutexB.acquire()
  print('33[43m%s拿到B锁33[0m'%self.name)
  time.sleep(2)
  mutexA.acquire()
  print('33[44m%s拿到A锁33[0m'%self.name)
  mutexA.release()
  mutexB.release()
  if __name__=='__main__':
  for i in range(10):
  t=MyThread()
  t.start()


  综上所述,这篇内容就给大家介绍到这里了,希望可以给各位读者带来帮助。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128438.html

相关文章

  • 【Java并发编程的艺术】第一章读书笔记

    摘要:前言并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。尽可能降低上下文切换的次数,有助于提高并发效率。死锁并发编程中的另一挑战是死锁,会造成系统功能不可用。 前言 并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。有以下几种挑战。 挑战及方案 上下文切换 单核CPU上执行多线程任务,通过给每个线程分配CPU时间片的方式来实现这个机制。...

    马忠志 评论0 收藏0
  • 使用Python和Java调用Shell脚本时的死锁陷阱

    摘要:一般使用或者调用外部脚本需要注意的是,这里的方向是相对于主程序的,所以就是子进程的输出,而是子进程的输入。基于同样的原因,假如调用了方法等待子进程执行完毕而没有及时处理输出的话,就会造成死锁。 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件...

    freewolf 评论0 收藏0
  • 使用Python和Java调用Shell脚本时的死锁陷阱

    摘要:一般使用或者调用外部脚本需要注意的是,这里的方向是相对于主程序的,所以就是子进程的输出,而是子进程的输入。基于同样的原因,假如调用了方法等待子进程执行完毕而没有及时处理输出的话,就会造成死锁。 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件...

    wow_worktile 评论0 收藏0
  • Java锁之重入锁

    摘要:通过关键字可以实现多线程之间的同步控制,除了上述方法,为我们提供了很多并发控制的工具类,今天主要讲的就是中的重入锁,效果基本等同于关键字。 在讲重入锁之前,我们先看一段代码showImg(https://segmentfault.com/img/bV0FmF?w=1198&h=878);上述代码想要实现的效果,就是使用两个线程对i分别进行累加一百万次,最终希望i的值是二百万,如果按照上...

    Jinkey 评论0 收藏0
  • 线程死锁就是这么简单

    摘要:此时线程需要锁才能继续往下执行。但是线程的锁并没有释放,线程的锁也没有释放。 前言 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制了解一下 AQS简简单单过一遍 Lock锁子类了解一下 线程池你真不来了解一下吗? 本篇主要是讲解死锁,这是我在多线程的最后一篇了。主要将多线程...

    winterdawn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<