摘要

由于多线程共享进程的资源和地址空间,因此,在对这些公共资源进行操作时,为了防止这些公共资源出现异常的结果,必须考虑线程的同步和互斥问题。

为什么加锁:1、用于非线程安全, 2、控制一段代码,确保其不产生调度混乱。

threading.Lock的用法

下面是一个python多线程的例子:

import threading
count = 0 def print_time(threadName):
global count
c=0
while(c<100):
c+=1
count+=1
print("{0}: set count to {1}".format( threadName, count) ) try:
threading.Thread( target=print_time, args=("Thread-1", ) ).start()
threading.Thread( target=print_time, args=("Thread-2", ) ).start()
threading.Thread( target=print_time, args=("Thread-3", ) ).start()
except Exception as e:
print("Error: unable to start thread")

在这个例子中,我们start了3个线程,每个线程都会对全局资源count进行改写操作。得到的结果如下,每个thread都会交替对count值进行修改。

Thread-1: set count to 198
Thread-2: set count to 199
Thread-1: set count to 200
Thread-2: set count to 201
Thread-1: set count to 202
Thread-2: set count to 203
Thread-1: set count to 204
Thread-2: set count to 205

我们可以对上例中的print_time()中访问资源的代码加锁,就可以把这个函数变为线程安全的函数。具体代码如下:

import threading

count = 0
lock = threading.Lock() def print_time(threadName):
global count c=0
with lock:
while(c<100):
c+=1
count+=1
print("{0}: set count to {1}".format( threadName, count) ) try:
threading.Thread( target=print_time, args=("Thread-1", ) ).start()
threading.Thread( target=print_time, args=("Thread-2", ) ).start()
threading.Thread( target=print_time, args=("Thread-3", ) ).start()
except Exception as e:
print("Error: unable to start thread")

通过threading.Lock(),就能实现加锁。这样每个thread对count进行改动期间while(c<100),就不会有其它的thread插入进来改动count。得到的输出如下:

Thread-2: set count to 199
Thread-2: set count to 200
Thread-3: set count to 201
Thread-3: set count to 202
Thread-3: set count to 203
Thread-3: set count to 204

锁的使用,有两种方法,上面的是最简单的通过with lock来操作。

还有另一种用法,是通过Lock的acquire()和release()函数来控制加锁和解锁,如下例,得到的结果和上例相同:

import threading

count = 0
lock = threading.Lock() def print_time(threadName):
global count c=0
if(lock.acquire()):
while(c<100):
c+=1
count+=1
print("{0}: set count to {1}".format( threadName, count) )
lock.release()
try:
threading.Thread( target=print_time, args=("Thread-1", ) ).start()
threading.Thread( target=print_time, args=("Thread-2", ) ).start()
threading.Thread( target=print_time, args=("Thread-3", ) ).start()
except Exception as e:
print("Error: unable to start thread")

Lock与RLock的区别

在threading模块中,定义两种类型的琐:threading.Lock和threading.RLock。它们之间有一点细微的区别,通过比较下面两段代码来说明:

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()

这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。

Python 中的Lock与RLock的更多相关文章

  1. python threading编程中的LOCK和RLOCK(可重入锁)

    找到一本PYTHON并发编辑的书, 弄弄.. #!/usr/bin/env python # -*- coding: utf-8 -*- import threading import time sh ...

  2. python中的Lock

    #Lock.py from multiprocessing import Process,Lock import os def f(l,i): l.acquire() print('hello wor ...

  3. Python中的多线程编程,线程安全与锁(一)

    1. 多线程编程与线程安全相关重要概念 在我的上篇博文 聊聊Python中的GIL 中,我们熟悉了几个特别重要的概念:GIL,线程,进程, 线程安全,原子操作. 以下是简单回顾,详细介绍请直接看聊聊P ...

  4. Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)

    1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...

  5. python threading模块的Lock和RLock区别

    首先了解这两者是什么. 以下说明参考自python官网 Lock:Lock被称为①原始锁,原始锁是一个②在锁定时不属于特定线程的同步基元组件,它是能用的最低级的同步基元组件.原始锁处于 "锁 ...

  6. python多线程锁lock/Rlock/BoundedSemaphore/Condition/Event

    import time import threading lock = threading.RLock() n = 10 def task(arg): # 加锁,此区域的代码同一时刻只能有一个线程执行 ...

  7. Python中的threading

    Python中的threading RLock--重入锁 RLock在Python中的实现是对Lock的封装,具体在类中维护了一个重入次数的变量.一旦一个线程获得一个RLock,该线程再次要求获得该锁 ...

  8. python中的进程、线程(threading、multiprocessing、Queue、subprocess)

    Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...

  9. python中的多线程【转】

    转载自: http://c4fun.cn/blog/2014/05/06/python-threading/ python中关于多线程的操作可以使用thread和threading模块来实现,其中th ...

随机推荐

  1. Linux安装部署FTP服务器

    Linux安装部署FTP服务器   本文章会将安装FTP服务器的步骤以及一些遇到的问题来记录下 因为项目中要与第三方对接数据,需要用到FTP服务器以提供他们每天上传数据,因为之前在本地的VMware虚 ...

  2. Vue.use源码分析(转)+如何封装一个组件

    封装一个组件:https://www.jianshu.com/p/89a05706917a 我想有过vue开发经验的,对于vue.use并不陌生.当使用vue-resource或vue-router等 ...

  3. JavaScript Map 和 Object 的区别

    不同点 Key filed 在 Object 中, key 必须是简单数据类型(整数,字符串或者是 symbol),而在 Map 中则可以是 JavaScript 支持的所有数据类型,也就是说可以用一 ...

  4. springMVC @response 中文乱码解决

    以下任选一种 在web.xml中: 添加一个过滤器(filter),注册 org.springframework.web.filter.CharacterEncodingFilter <filt ...

  5. Jupiter Code Review Reference -- Jupiter代码审查工具使用参考

    Jupiter Code Review Reference -- Jupiter代码审查工具使用参考 (修改版) 原创 2010年07月06日 10:43:00 标签: 审查 / reference  ...

  6. debian配置国内软件源

    本例在debian:buster-slim docker镜像中实验通过 1.启动docker实例 docker run -it --name debian debian:buster-slim bas ...

  7. 后台以json数据形式返回之后前台接受的方法以及之后的解析总结

    1.前台AJAX请求,后台以对象转JSON形式返回: 后台代码: @RequestMapping(value = "/queryDist", method = RequestMet ...

  8. Lombok 注解简介

    Lombok @AllArgsConstructor /** * 生成一个包含所有属性的构造函数 */ @Target(ElementType.TYPE) @Retention(RetentionPo ...

  9. python - socket通信笔记

    参考: 通过编写聊天程序来熟悉python中多线程和socket的用法:https://www.cnblogs.com/mingjiatang/p/4905395.html python socket ...

  10. 系统分析与设计HW2

    简答题 1. 简述瀑布模型.增量模型.螺旋模型(含原型方法)的优缺点. 瀑布模型 优点: 定义了软件开发基本流程与活动. 为项目提供了按阶段划分的检查点. 当前一阶段完成后,只需关注后续阶段. 缺点: ...