1、基本概念

  如果想让只有拿到锁的线程才能释放该锁,那么应该使用RLock()对象。当需要在类外面保证线程安全,又要在类内使用同样方法的时候RLock()就很使用。

  RLock叫做Reentrant Lock,就是可以重复进入的锁,也叫递归锁。这种锁对比Lock有三个特点:1、谁拿到锁,谁释放;2、同一线程可以多次拿到该锁;3、acquire多少次就必须release多少次,只有最后一次release才能改变RLock的状态为unlocked。

2、RLock示例代码

# coding:utf-8

import threading
import time class Box(object):
lock = threading.RLock() def __init__(self):
self.total_items = 0 def execute(self, n):
Box.lock.acquire()
self.total_items += n
Box.lock.release() def add(self):
Box.lock.acquire()
self.execute(1)
Box.lock.release() def remove(self):
Box.lock.acquire()
self.execute(-1)
Box.lock.release() def adder(box, items):
while items > 0:
print("adding 1 item in the box")
box.add()
time.sleep(1)
items -= 1
def remover(box, items):
while items > 0:
print("removing 1 item in the box")
box.remove()
time.sleep(1)
items -= 1 if __name__ == "__main__":
items = 5 print("putting %s items in the box" %items)
box = Box()
t1 = threading.Thread(target=adder, args=(box, items))
t2 = threading.Thread(target=remover, args=(box, items)) t1.start()
t2.start() t1.join()
t2.join()
print("%s items still remain in the box " % box.total_items)

上述代码中adder()和remover()两个函数在Box类内操作items,即调用Box类的方法:add()和remove()。每一次方法调用,都会有一次拿到资源然后释放资源的过程。至于lock()对象,RLock()对象有acquire()和release()方法可以拿到或释放资源;每一次方法调用中,都有一下操作:

    Box.lock.acquire()

    do something

    Box.lock.release()

运行结果如下:

Python并行编程(四):线程同步之RLock的更多相关文章

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

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

  2. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  3. python并发编程之线程/协程

    python并发编程之线程/协程 part 4: 异步阻塞例子与生产者消费者模型 同步阻塞 调用函数必须等待结果\cpu没工作input sleep recv accept connect get 同 ...

  4. .NET面试题解析(07)-多线程编程与线程同步

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...

  5. .NET面试题解析(07)-多线程编程与线程同步 (转)

    http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...

  6. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...

  7. Python并行编程(五):线程同步之信号量

    1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...

  8. Python并行编程(三):线程同步之Lock

    1.基础概念 当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码.bug等异常行为. 竞争条件最简单的解决方法是使用锁.锁的操 ...

  9. Python并行编程(十四):异步编程

    1.基本概念 除了顺序执行和并行执行的模型以外,还有异步模型,这是事件驱动模型的基础.异步活动的执行模型可以只有一个单一的主控制流,能在单核心系统和多核心系统中运行. 在并发执行的异步模型中,许多任务 ...

随机推荐

  1. PDF文件的加载及展示

    项目需要显示PDF文件,于是遍寻了网络,发现的方法以下几种: 1.使用UIWebView加载,没啥说的,根据文件路径,网络或者本地皆可,创建一个NSURLRequest,然后用webView加载就可以 ...

  2. PHP面对对象总结

    一个关于面对对象知识的问答总计:https://wenku.baidu.com/view/391eeec483c4bb4cf6ecd1ad.html 面对对象的三大特征: 1.封装 为了保护类封装了之 ...

  3. [Eth]网络查看命令:route

    最近在调试网络,出现问题,两个网口分别接外网内网,结果不同 http://www.cnblogs.com/peida/archive/2013/03/05/2943698.html

  4. centos7系统根目录扩容

    比如 点击了后 点击创建虚拟磁盘 选择一个 20G  然后启动虚拟机使用fdisk查看所有的磁盘 看是否新增了一个20G的硬盘 [root@localhost ~]# fdisk -l 磁盘 /dev ...

  5. php -- 四种基础排序:冒泡、选择、插入、快速

    冒泡排序 思路分析:法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来. 第一轮:从第一个到最后一个冒泡比较,运行结果:最后一个最大 第二轮:从第一个到倒数第二个冒泡比较, 运行结果:最后一 ...

  6. 【BZOJ】1620: [Usaco2008 Nov]Time Management 时间管理(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1620 一开始想不通啊.. 其实很简单... 每个时间都有个完成时间,那么我们就从最大的 完成时间的开 ...

  7. JQuery获取和设置select下拉框的值

    获取Select : 获取select 选中的 text : $("#sid").find("option:selected").text(); 获取selec ...

  8. jQuery的end()方法使用详解

    end()方法的定义和用法: end()方法能够回到最近的一个"破坏性"操作之前,即将匹配的元素列表变为前一次的状态.如果没有破坏性操作将返回一个空集.破坏性操作的概念:指任何改变 ...

  9. iOS TabBar添加阴影

    效果图如下所示: 直接上代码 //移除顶部线条 self.tabBar.backgroundImage = [UIImage new]; self.tabBar.shadowImage = [UIIm ...

  10. 编程之美 set 11 买书问题

    题目 书店搞促销, 同时购买多卷书时, 有机会享受优惠 2本优惠 5%, 3本 10%, 4 本 20% 5 本 25% 设计算法, 求解购买一本书的最低价格 分析 1. 第一个感觉是一次购买的越多省 ...