摘要

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

为什么加锁: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. Spring Boot教程(十)异步方法测试

    测试 测试代码如下: @Component public class AppRunner implements CommandLineRunner { private static final Log ...

  2. Getting CFNetwork SSLHandshake failed (-9806) error

    平常个人打测试包一切OK,今天突然不能联网了 How to handle "CFNetwork SSLHandshake failed" in iOS 参考1 Getting CF ...

  3. modern php笔记---php (性状)

    modern php笔记---php (性状) 一.总结 一句话总结: trait是和继承一个层次的东西 一个类use MyTrait;后,trait中的方法覆盖父类方法,当前类中的方法覆盖trait ...

  4. HashMap,ConcurrentHashMap相关知识整理

    1.HashMap的存储步骤: 1.传入key和value,判断key是否为null,如果为null,则调用putForNullKey,以null作为key存储到哈希表中: 2. 然后计算key的ha ...

  5. JS中设置cookie,读取cookie,删除cookie

    在开发时,碰到一个需求,需要保存一个表的信息(非隐私),希望下次打开还存在.于是想到用cookie,一番折腾完成.示例数据都是假的,打马赛克是怕泄密. 这个表取名为Data,为Array,每一行是一个 ...

  6. Appium关键字

    *** Settings *** Library AppiumLibrary Library AutoItLibrary Library os *** Keywords *** xpath应该匹配次数 ...

  7. Mysql-5.7 x64安装

    首先在官网下载Mysql:https://dev.mysql.com/downloads/mysql/ 选择ZIP Archive下载. 下载安装之后配置环境变量: 编辑现有环境变量Path: PS: ...

  8. 4.1.k8s.svc(Service)

    #Service Service为Pod提供4层负载均衡, 访问 -> Service -> Pod组 #4种类型 ClusterIP 默认,分配一个VIP,只能内部访问 NodePort ...

  9. 类Enum

    int compareTo(E o) 比较此枚举与指定对象的顺序. String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明. int ordinal() 返回枚举常量的序数(它在 ...

  10. spring boot + mybatis 连接 oracle 出现 ORA-00923: 未找到要求的 FROM 关键字 错误

    1.原因 hikari 连接池配置错误,mysql和oracle的配置不一样 2.修改 spring: datasource: hikari: connection-test-query: selec ...