一:死锁

  所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程成为死锁进程。多个lock会造成死锁

二:递归锁和线程锁差异

  在threading模块中,定义两种类型的琐:threading.Lock和threading.RLock

  这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。

  而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,

  必须调用n次的release才能真正释放所占用的琐。它们之间有一点细微的区别,通过比较下面两段代码来说明:

  递归锁与普通的互斥锁最大的不同就是,一个锁的对象内部,维护了一个计数器,这个计数器的初始值是0,

  当一个线程acquire一次这个锁时,内部计数器+1,但是,这把锁的计数器一旦大于0,其他的线程是无法拿到这把锁的,只有当前线程可以拿。

  (当前线程acquire一次,计数器+1,release一次计数器-1,所以,当前的线程想要彻底释放掉递归锁,acquire多少次,就要release多少次!!!)

import threading
lock = threading.Lock() #Lock对象
lock.acquire()
lock.acquire() #产生了死琐。
lock.release() lock.release() import threading
rLock = threading.RLock() #RLock对象
rLock.acquire()
rLock.acquire() #在同一线程内,程序不会堵塞。
rLock.release()
rLock.release()

三:递归锁使用例子

import threading,time

def run1():

    print("grab the first part data")

    lock.acquire()

    global num

    num +=1

    lock.release()

    return num

def run2():

    print("grab the second part data")

    lock.acquire()

    global  num2

    num2+=1

    lock.release()

    return num2

def run3():

    lock.acquire()

    res = run1()

    print('--------between run1 and run2-----')

    res2 = run2()

    lock.release()

    print(res,res2)

if __name__ == '__main__':

    num,num2 = 0,0

    lock = threading.RLock()

    for i in range(10):

        t = threading.Thread(target=run3)

        t.start()

while threading.active_count() != 1:

    print(threading.active_count())

else:

    print('----all threads done---')

    print(num,num2)

 四:总结

  

  如果同一个线程需要多次去访问同一个共享资源,这个时候,就可以使用递归锁(RLock)

  递归锁的内部,维护了一个Lock对象和一个counter计数变量,counter记录了acquire的次数,从而使得资源可以被多次require。

  直到一个线程所有的acquire都被release,其他的线程才能获得资源。

  所以说RLock可以完全代替Lock,能用递归锁尽量用递归锁!

python网络编程--线程递归锁RLock的更多相关文章

  1. python网络编程--线程(锁,GIL锁,守护线程)

    1.线程 1.进程与线程 进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率.很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观 ...

  2. python并发编程-线程和锁

    什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: from multiprocessing import Pr ...

  3. python网络编程--线程锁(互斥锁Mutex)

    一:为什么需要线程锁 一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况? 很简单,假设你有A,B两 ...

  4. python网络编程--线程GIL(全局解释器锁)

    一:什么是GIL 在CPython,全局解释器锁,或GIL,是一个互斥体防止多个本地线程执行同时修改同一个代码.这把锁是必要的主要是因为当前的内存管理不是线程安全的.(然而,由于GIL存在,其他特性已 ...

  5. python网络编程-线程队列queue

    一:线程queu作用 Python中,queue是线程间最常用的交换数据的形式. 队列两个作用:一个是解耦,一个是提高效率 二:语法 1)队列的类 class queue.Queue(maxsize= ...

  6. python网络编程--线程使用threading

    一:线程使用 线程使用有两种方法,一种是直接使用,二是通过继承threading.Thread类使用 二:函数式使用 函数式:调用thread模块中的start_new_thread()函数来产生新线 ...

  7. python网络编程中互斥锁与进程之间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  8. python网络编程之互斥锁

    标签(空格分隔): 互斥锁 进程之间的数据不共享,但是共享同一套文件系统,所以访问同一个文件,或者同一个打印终端,是没有问题的,而共享带来的问题就是竞争,竞争带来的结果就是错乱,如下: #并发运行,效 ...

  9. python网络编程--线程event

    一:线程event作用 Python提供了Event对象用于线程间通信,它是线程设置的信号标志,如果信号标志位真,则其他线程等待直到信号结束. Event对象实现了简单的线程通信机制,它提供了设置信号 ...

随机推荐

  1. 数字表格(product)

    Description Solution 一开始的时候我是这么推的(\(f(n)\)表示斐波那契数列的第\(n\)项) \[ \begin{aligned} Ans&=\prod_{x=1}^ ...

  2. 【bzoj1396】 识别子串

    http://www.lydsy.com/JudgeOnline/problem.php?id=1396 (题目链接) 题意 问字符串S每一位的最短识别子串是多长(识别子串指包含这个字符且只出现在S中 ...

  3. python之旅:模块与包

    一.模块介绍 前言:引用廖雪峰大神的,说的很好!!! 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放 ...

  4. Go_18: Golang 中三种读取文件发放性能对比

    Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提 ...

  5. 科学计算三维可视化---Mlab基础(基于Numpy数组的绘图函数)

    Mlab了解 Mlab是Mayavi提供的面向脚本的api,他可以实现快速的三维可视化,Mayavi可以通过Mlab的绘图函数对Numpy数组建立可视化. 过程为: .建立数据源 .使用Filter( ...

  6. 机器学习算法整理(一)线性回归与梯度下降 python实现

    回归算法 以下均为自己看视频做的笔记,自用,侵删! 一.线性回归 θ是bias(偏置项) 线性回归算法代码实现 # coding: utf-8 ​ get_ipython().run_line_mag ...

  7. ngx_lua_API 指令详解(一)ngx.timer.at 指令

    语法: ok,err = ngx.timer.at(delay,callback,user_arg1,user_arg2 ...) 上下文: init_worker_by_lua *,set_by_l ...

  8. Django 2.0.1 官方文档翻译:接下来读什么(page 14)

    接下来读什么(page 14) 现在你应该已经阅读了所有的(page1-13 )介绍材料,决定继续使用Django.我们仅仅做了简要的介绍(事实上,如果你阅读了前面所有的内容,也只是全部文档的5%.) ...

  9. Java并发编程原理与实战十四:Lock接口的认识和使用

    保证线程安全演进: synchronized volatile AtomicInteger Lock接口提供的方法: void lock():加锁 void unlock():解锁 void lock ...

  10. HttpContext.Current為空匯總

    1. async異步模式下為空 解决办法: <httpRuntime targetFramework="4.5" /> 或者: In your appSettings, ...