小编写这篇文章的一个主要目的,主要是来给大家进行阐述关于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
摘要:前言并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。尽可能降低上下文切换的次数,有助于提高并发效率。死锁并发编程中的另一挑战是死锁,会造成系统功能不可用。 前言 并发编程的目的是让程序跑的更快,但并不是启动更多的线程,这个程序就跑的更快。有以下几种挑战。 挑战及方案 上下文切换 单核CPU上执行多线程任务,通过给每个线程分配CPU时间片的方式来实现这个机制。...
摘要:一般使用或者调用外部脚本需要注意的是,这里的方向是相对于主程序的,所以就是子进程的输出,而是子进程的输入。基于同样的原因,假如调用了方法等待子进程执行完毕而没有及时处理输出的话,就会造成死锁。 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件...
摘要:一般使用或者调用外部脚本需要注意的是,这里的方向是相对于主程序的,所以就是子进程的输出,而是子进程的输入。基于同样的原因,假如调用了方法等待子进程执行完毕而没有及时处理输出的话,就会造成死锁。 最近有一项需求,要定时判断任务执行条件是否满足并触发 Spark 任务,平时编写 Spark 任务时都是封装为一个 Jar 包,然后采用 Shell 脚本形式传入所需参数执行,考虑到本次判断条件...
摘要:此时线程需要锁才能继续往下执行。但是线程的锁并没有释放,线程的锁也没有释放。 前言 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制了解一下 AQS简简单单过一遍 Lock锁子类了解一下 线程池你真不来了解一下吗? 本篇主要是讲解死锁,这是我在多线程的最后一篇了。主要将多线程...
阅读 910·2023-01-14 11:38
阅读 877·2023-01-14 11:04
阅读 739·2023-01-14 10:48
阅读 1980·2023-01-14 10:34
阅读 941·2023-01-14 10:24
阅读 818·2023-01-14 10:18
阅读 498·2023-01-14 10:09
阅读 571·2023-01-14 10:02