死锁现象

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

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

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. 01.Java 开发简单的计算器

    难度为一般,适合具有 Java 基础和 Swing 组件编程知识的用户学习一. 实验介绍1.1 实验内容本次实验利用Java开发一个可以进行简单的四则运算的图形化计算器,会使用到 Java Swing ...

  2. 第15章:MongoDB-聚合操作--聚合管道--$match

    ①$match 用于对文档集合进行筛选,里面可以使用所有常规的查询操作符. 通常会放置在管道最前面的位置,理由如下: 1:快速将不需要的文档过滤,减少后续操作的数据量 2:在投影和分组之前做筛选,查询 ...

  3. hibernate4.3.5,Final hibernate.cfg.xml的配置

    今天是接触hibernate的第二天,用来练习的是hibernate最新的版本hibernate-release-4.3.5.Final 要使用hibernate,则先要引入它的jar包,要引入的ja ...

  4. Keras预测股票

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sat Nov 18 21:22:29 201 ...

  5. winSockets编程(二)socket函数

    初始化DLL之后,接着创建套接字,通过socket()和WSASocket()函数实现此功能. SOCKET socket( int af, int type, int protocol ); af: ...

  6. 用Dagger2在Android中实现依赖注入

    依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的.使应用开发更加可扩展,更容易维护.通过本文你会学到如何使用Dagger2来处理依赖. 简介 如果以对象需要另外的一个对象才能 ...

  7. web百度地图跨域问题

    //根据经纬度获取地理位置信息function latOrLng(sLat, sLng) { var resUrl = 'http://api.map.baidu.com/geocoder/v2/?a ...

  8. _编程语言_C_C++_数据结构_struct

    Struct 语句,访问成员使用 点结构. Example: #include <iostream> #include <cstring> using namespace st ...

  9. HDU1853 Cyclic Tour

    Cyclic Tour                                                                                Time Limi ...

  10. PAT甲级 1126. Eulerian Path (25)

    1126. Eulerian Path (25) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue In grap ...