一、线程锁

Threading模块为我们提供了一个类,Threading.Lock锁。我们创建一个该类对象,在线程函数执行前,“抢占”该锁,执行完成后,“释放”该锁,则我们确保了每次只有一个线程占有该锁。这时候对一个公共的对象进行操作,则不会发生线程不安全的现象了。

1、我们先建立了一个threading.Lock类对象lock,在run方法里,我们使用lock.acquire()获得了这个锁。此时,其他的线程就无法再获得该锁了,他们就会阻塞在“if lock.acquire()”这里,直到锁被另一个线程释放:lock.release()。

2、如果多个线程要调用多个现象,而A线程调用A锁占用了A对象,B线程调用了B锁占用了B对象,A线程不能调用B对象,B线程不能调用A对象,于是一直等待。这就造成了线程“死锁”。

Threading模块中,也有一个类,RLock,称之为可重入锁。该锁对象内部维护着一个Lock和一个counter对象。counter对象记录了acquire的次数,使得资源可以被多次require。最后,当所有RLock被release后,其他线程才能获取资源。在同一个线程中,RLock.acquire可以被多次调用,利用该特性,可以解决部分死锁问题

3、当多个线程同时访问一个数据时,需加锁,排队变成单线程一个一个执行

4、加锁避免并发导致逻辑出错

5、每当一个线程a要访问共享数据时,必须先获得锁定;如果已经有别的线程b获得锁定了,那么就让线程a暂停,也就是同步阻塞;等到线程b访问完毕,释放锁以后,再让线程a继续

6、语法

lock=threading.Lock() #创建线程锁

lock = threading.RLock()#创建递归锁(多个锁时用这个)

lock.acquire() #锁住

lock.release() 释放锁

二、线程锁实例

#未加锁
如果多个线程同时操作某个数据,会出现不可预料的结果。比如以下场景:当小伙伴a在往火锅里面添加鱼丸的时候,小伙伴b在同时吃掉鱼丸,这很有可能导致刚下锅的鱼丸被夹出来了(没有熟),或者还没下锅,就去夹鱼丸(夹不到)# coding=utf-8
import threading
import time
def chiHuoGuo(people, do):print("%s 吃火锅的小伙伴:%s" % (time.ctime(),people))time.sleep(1)for i in range(3):time.sleep(1)print("%s %s正在 %s 鱼丸"% (time.ctime(), people, do))print("%s 吃火锅的小伙伴:%s" % (time.ctime(),people))
class myThread (threading.Thread):   # 继承父类threading.Threaddef __init__(self, people, name, do):'''重写threading.Thread初始化内容'''threading.Thread.__init__(self)self.threadName = nameself.people = peopleself.do = dodef run(self):   # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数'''重写run方法'''print("开始线程: " + self.threadName)chiHuoGuo(self.people, self.do)     # 执行任务print("结束线程: " + self.name)
print("yoyo请小伙伴开始吃火锅:!!!")
# 设置线程组
threads = []
# 创建新线程
thread1 = myThread("xiaoming", "Thread-1", "添加")
thread2 = myThread("xiaowang", "Thread-2", "吃掉")
# 添加到线程组
threads.append(thread1)
threads.append(thread2)
# 开启线程
for thread in threads:thread.start()
# 阻塞主线程,等子线程结束
for thread in threads:thread.join()
time.sleep(0.1)
print("退出主线程:吃火锅结束,结账走人")C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py
yoyo请小伙伴开始吃火锅:!!!
开始线程: Thread-1
Fri Mar 15 08:33:19 2019 吃火锅的小伙伴:xiaoming
开始线程: Thread-2
Fri Mar 15 08:33:19 2019 吃火锅的小伙伴:xiaowang
Fri Mar 15 08:33:21 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:33:21 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:33:22 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:33:22 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:33:23 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:33:23 2019 吃火锅的小伙伴:xiaowang
结束线程: Thread-2
Fri Mar 15 08:33:23 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:33:23 2019 吃火锅的小伙伴:xiaoming
结束线程: Thread-1
退出主线程:吃火锅结束,结账走人Process finished with exit code 0
#线程锁,单锁实例
import time,threading
def run(n):lock.acquire() #加锁global numnum+=1lock.release() #释放锁
lock=threading.Lock()#获得线程锁
num=0
threads=[]
for i in range(50):thread=threading.Thread(target=run,args=("t-%s"%i,))thread.start()threads.append(thread)
for i in threads:i.join()
print("num:",num)C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py
num: 50Process finished with exit code 0
#线程锁,加锁实例# coding=utf-8
import threading
import time
def chiHuoGuo(people, do):print("%s 吃火锅的小伙伴:%s" % (time.ctime(),people))time.sleep(1)for i in range(3):time.sleep(1)print("%s %s正在 %s 鱼丸"% (time.ctime(), people, do))print("%s 吃火锅的小伙伴:%s" % (time.ctime(),people))
class myThread (threading.Thread):   # 继承父类threading.Threadlock = threading.Lock()  # 线程锁def __init__(self, people, name, do):'''重写threading.Thread初始化内容'''threading.Thread.__init__(self)self.threadName = nameself.people = peopleself.do = dodef run(self):   # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数'''重写run方法'''print("开始线程: " + self.threadName)# 执行任务之前锁定线程self.lock.acquire()chiHuoGuo(self.people, self.do)     # 执行任务# 执行完之后,释放锁self.lock.release()print("结束线程: " + self.name)
print("yoyo请小伙伴开始吃火锅:!!!")
# 设置线程组
threads = []
# 创建新线程
thread1 = myThread("xiaoming", "Thread-1", "添加")
thread2 = myThread("xiaowang", "Thread-2", "吃掉")
# 添加到线程组
threads.append(thread1)
threads.append(thread2)
# 开启线程
for thread in threads:thread.start()
# 阻塞主线程,等子线程结束
for thread in threads:thread.join()
time.sleep(0.1)
print("退出主线程:吃火锅结束,结账走人")C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py
yoyo请小伙伴开始吃火锅:!!!
开始线程: Thread-1
Fri Mar 15 08:36:39 2019 吃火锅的小伙伴:xiaoming
开始线程: Thread-2
Fri Mar 15 08:36:41 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:36:42 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:36:43 2019 xiaoming正在 添加 鱼丸
Fri Mar 15 08:36:43 2019 吃火锅的小伙伴:xiaoming
结束线程: Thread-1
Fri Mar 15 08:36:43 2019 吃火锅的小伙伴:xiaowang
Fri Mar 15 08:36:45 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:36:47 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:36:48 2019 xiaowang正在 吃掉 鱼丸
Fri Mar 15 08:36:48 2019 吃火锅的小伙伴:xiaowang
结束线程: Thread-2
退出主线程:吃火锅结束,结账走人Process finished with exit code 0
#线程锁,多个锁时,需加递归锁import threading, time
def run1():print("grab the first part data")lock.acquire()global numnum += 1lock.release()return num
def run2():print("grab the second part data")lock.acquire()global num2num2 += 1lock.release()return num2
def run3():lock.acquire()res = run1()print('--------between run1 and run2-----')res2 = run2()lock.release()print(res, res2)
num, num2 = 0, 0
lock = threading.RLock() #递归锁
for i in range(3):t = threading.Thread(target=run3)t.start()
while threading.active_count() != 1:print(threading.active_count())
else:print('----all threads done---')print(num, num2)

python多线程之线程锁(Lock)和递归锁(RLock)实例相关推荐

  1. php和python的多线程,Python多线程以及线程锁简单理解(代码)

    本篇文章给大家带来的内容是关于Python多线程以及线程锁简单理解(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 多线程threading 模块创建线程创建自己的线程类线程通 ...

  2. 11.python并发入门(part4 死锁与递归锁)

    一.关于死锁. 死锁,就是当多个进程或者线程在执行的过程中,因争夺共享资源而造成的一种互相等待的现象,一旦产生了死锁,不加人工处理,程序会一直等待下去,这也被称为死锁进程. 下面是一个产生" ...

  3. python多线程结束线程_Python多线程和Office第2部分

    python多线程结束线程 This is the second and final part of the series. You can find the first part of the bl ...

  4. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  5. python多线程守护线程_Python守护程序线程

    python多线程守护线程 In this tutorial we will be learning about Python Daemon Thread. In our previous tutor ...

  6. python多线程结束线程_Python线程– Python多线程

    python多线程结束线程 Python threading module is used to implement multithreading in python programs. In thi ...

  7. 自旋锁/互斥锁/读写锁/递归锁的区别与联系

    自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁 ...

  8. python中gil锁和线程锁_Python线程——GIL锁、线程锁(互斥锁)、递归锁(RLock)...

    GIL锁 ​ 计算机有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让看上去是并发的.但是单核永远肯定时串行的,它肯定是串行 ...

  9. python中的多线程 GIL(全局解释器锁) 死锁与递归锁

    1.什么的是线程 在程序里一个执行路线就叫做线程,线程是程序执行的最小单位 2.多线程的优点 使用线程可以把占据长时间的程序中的任务放到后台去处理. 在处理I/O密集程序的运行速度可能加快(ps:计算 ...

最新文章

  1. 每天进步一点点——Linux文件锁编程flock
  2. python3 字符串填充 清除
  3. Spring Boot - 构建数据访问层
  4. JSP九大内置对象...
  5. c++ 顺序容器list的一个例子
  6. 洛谷 动态规划一日游 P2577、P1070、P2051
  7. 一些关于Spring的随笔
  8. 使用脚本删除ios工程中未使用图片
  9. 开发环境入门 linux基础 (部分)while for 函数 计划任务
  10. 原生js制作PC端轮播图
  11. 使用socat实现对asok的远程访问
  12. ts视频合并---P站
  13. IDEA SVN拉下来的项目import project 没反应 解决方案
  14. 【css】鼠标禁用样式
  15. 【读书笔记-诗词歌赋】诗词积累(一)
  16. ESP8266_CH340G串口自动下载固件库原理
  17. npm 更新 npm_您可以使用8 npm技巧来打动同事
  18. Leetcode-数据结构-350. 两个数组的交集 II
  19. java 内存溢出 jstack,Java——命令jps、jstat、jmap、jstack、jhat、jinfo
  20. vue路由懒加载的两种方式

热门文章

  1. java servlet是单例吗_关于java:为什么apache servlet是单例?
  2. c语言中foreach的用法,详解JavaScript中的forEach()方法的使用
  3. java 计算反码_java基础知识-原码、反码、补码、运算符
  4. js中立即执行函数会预编译吗_作为前端你了解JavaScript运行机制吗?
  5. coreos 安装mysql_如何执行CoreOS Linux的裸机安装
  6. 小红书点赞收藏有什么用_橱柜门用什么材料好?老师傅开口说话了!听进去算你的,收藏备用...
  7. aix查看oracle数据库端口号,通过netstat+rmsock查找AIX端口对应进程
  8. 如何抓取html请求,怎么获取请求头
  9. 算法训练 瓷砖铺放 递归
  10. java游戏猿人时代_学习java编程就业前景如何