死锁现象

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

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

from threading import Thread,Lock
import time mutexA = Lock()
mutexB = Lock() class MyThread(Thread):
def run(self):
self.task1()
self.task2() def task1(self):
mutexA.acquire()
print('%s task1 get A' %self.name) mutexB.acquire()
print('%s task1 get B' % self.name)
mutexB.release() mutexA.release() def task2(self):
mutexB.acquire()
print('%s task2 get B' % self.name)
time.sleep(1) # Thread-2 拿到执行权,执行get A出现死锁,此时thread2需要B锁,而thread1占用,与此同时,thread1需要A锁,thread2占用
mutexA.acquire()
print('%s task2 get A' % self.name) mutexA.release()
mutexB.release() if __name__ == '__main__':
for i in range(10):
t = MyThread()
t.start() -------------------输出
Thread-1 task1 get A
Thread-1 task1 get B
Thread-1 task2 get B
Thread-2 task1 get 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() class MyThread(Thread):
def run(self):
self.task1()
self.task2() def task1(self):
mutexA.acquire()
print('%s task1 get A' %self.name) mutexB.acquire()
print('%s task1 get B' % self.name)
mutexB.release() mutexA.release()
time.sleep(1) # Thread-2 拿到执行权,,此时counter=0,thread2执行task1 def task2(self):
mutexB.acquire()
print('%s task2 get B' % self.name) mutexA.acquire()
print('%s task2 get A' % self.name) mutexA.release()
mutexB.release() if __name__ == '__main__':
for i in range(10):
t = MyThread()
t.start() ------------------------输出 Thread-1 task1 get A
Thread-1 task1 get B
Thread-2 task1 get A
Thread-2 task1 get B
Thread-3 task1 get A
Thread-3 task1 get B
Thread-4 task1 get A
Thread-4 task1 get B
Thread-5 task1 get A
Thread-5 task1 get B
Thread-6 task1 get A
Thread-6 task1 get B
Thread-7 task1 get A
Thread-7 task1 get B
Thread-8 task1 get A
Thread-8 task1 get B
Thread-9 task1 get A
Thread-9 task1 get B
Thread-10 task1 get A
Thread-10 task1 get B
Thread-1 task2 get B
Thread-1 task2 get A
Thread-2 task2 get B
Thread-2 task2 get A
Thread-4 task2 get B
Thread-4 task2 get A
Thread-3 task2 get B
Thread-3 task2 get A
Thread-5 task2 get B
Thread-5 task2 get A
Thread-6 task2 get B
Thread-6 task2 get A
……

  

 

python线程死锁与递归锁的更多相关文章

  1. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  2. Python3 进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  3. python开发线程:死锁和递归锁&信号量&定时器&线程queue&事件evevt

    一 死锁现象与递归锁 进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...

  4. 26 python 初学(线程、同步锁、死锁和递归锁)

    参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html 并发:一段时间内做一些事情 并行:同时做多件事情 线程是操作系统能够进行运算调度的基本单位 ...

  5. Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量

    在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...

  6. python并发编程之线程(二):死锁和递归锁&信号量&定时器&线程queue&事件evevt

    一 死锁现象与递归锁 进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...

  7. Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures

    参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...

  8. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  9. 10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁

    一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Pyt ...

随机推荐

  1. 812. Largest Triangle Area

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  2. JSON.parse和JSON.stringify的区别

    JSON.stringify()的作用是将 JavaScript 值转换为 JSON 字符串, 而JSON.parse()可以将JSON字符串转为一个对象. 简单点说,它们的作用是相对的,我用JSON ...

  3. mount 移动硬盘出现的各种小问题

    1.fdisk -l 查看硬盘是否存在 2.新建要挂载硬盘的文件夹 mkdir  /disk   (如果想要挂载到已存在的目录就不要新建了) 3.挂载硬盘:mount /dev/sdc /disk 4 ...

  4. c# devexpress绘图 三角函数

    加标题: using System; using System.Windows.Forms; using DevExpress.XtraCharts; // ... namespace SideByS ...

  5. Ubuntu下安装pycharm并设置快捷方式

    作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7070327.html Ubuntu下安装pycharm并设置快捷方式 下载P ...

  6. python一键升级所有第三方库

    import pip from subprocess import call for dist in pip.get_installed_distributions(): call("pip ...

  7. 自定义cell的高度

    // //  RootTableViewController.m //  Share // //  Created by lanouhn on 15/1/20. //  Copyright (c) 2 ...

  8. DeepFace和GAN

    由于换脸技术的影响,现在造假视频的成本越来越低.AI换脸视频也越来越热门,甚至有一些已经达到了以假乱真的程度.虽然有明星反对表示无奈,可是.... 据报道,2018年,arXiv上发布了902篇GAN ...

  9. Java 判断字符串能否转化为数字的三种方法

    用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str.length();--i>=0;){ if (! ...

  10. 修改vsftpd的默认根目录

    修改ftp的根目录只要修改/etc/vsftpd/vsftpd.conf文件即可: 加入如下几行: local_root=/var/www/html chroot_local_user=YES ano ...