day47-线程-锁和死锁
#1、锁:防止多个线程同时读写某一块内存区域。
from threading import Thread
from threading import Lock
def func():
global n
lock.acquire()
n -= 1 #每一个线程在操作数据之前先拿到钥匙,操作完成之后,释放钥匙。
lock.release() n = 10
t_list = []
lock = Lock()
for i in range(10): #先开启所有子线程。
t = Thread(target=func)
t.start()
t_list.append(t)
[t.join() for t in t_list] #最后才让主线程等待所有子线程结束而结束。这样才能实现异步操作。
print(n) #2、RLock递归锁可以acquire多次和对应地release多次,Lock互斥锁只能acquire和release一次。
from threading import RLock
lock = RLock()
lock.acquire()
lock.acquire()
lock.acquire()
print('')
lock.release()
lock.release()
lock.release()
# # 3、死锁:在不同的线程当中(eat和eat1),恰好要对两个数据(筷子和面)进行操作,使用Lock会产生死锁,数据不安全。
# 科学家吃面:吃面需要同时有筷子和面才能吃到,A吃完面把筷子和面放下让给B,B拿到筷子和面才能吃。
# 下面例子的结果是有人拿到面拿不到筷子,有人拿到筷子拿不到面,形成死锁。
from threading import Lock
from threading import Thread
import time
def eat(name):
kz_lock.acquire()
print('%s拿到筷子了'%name)
m_lock.acquire()
print('%s拿到面了'%name)
print('%s可以吃面了'%name)
time.sleep(1)#因为cpu调度是无序的,设置睡眠1秒是为了把问题更好的发掘出来,否则就算执行很多次,出现问题是小概率事件。
m_lock.release()
kz_lock.release() def eat1(name):
m_lock.acquire()
print('%s拿到面了'%name)
kz_lock.acquire()
print('%s拿到筷子了'%name)
print('%s可以吃面了'%name)
kz_lock.release()
m_lock.release() kz_lock = Lock() #筷子锁
m_lock = Lock() #面锁
t = Thread(target=eat,args=('tom',))
t.start()
t1 = Thread(target=eat1,args=('marry',))
t1.start()
t2 = Thread(target=eat,args=('jack',))
t2.start()
t3 = Thread(target=eat1,args=('alex',))
t3.start()
# tom拿到筷子了
# tom拿到面了
# tom可以吃面了
# jack拿到筷子了
# marry拿到面了 #Rlock解决死锁问题:
from threading import RLock
from threading import Thread
import time
def eat(name):
kz_lock.acquire()
print('%s拿到筷子了'%name)
m_lock.acquire()
print('%s拿到面了'%name)
print('%s可以吃面了'%name)
time.sleep(1)
m_lock.release() #后面拿到的钥匙先还。
kz_lock.release() #前面拿到的钥匙后还。 def eat1(name):
m_lock.acquire()
print('%s拿到面了'%name)
kz_lock.acquire()
print('%s拿到筷子了'%name)
print('%s可以吃面了'%name)
kz_lock.release()
m_lock.release() kz_lock = m_lock = RLock() #筷子锁和面锁是同一把锁
t = Thread(target=eat,args=('tom',))
t.start()
t1 = Thread(target=eat1,args=('marry',))
t1.start()
t2 = Thread(target=eat,args=('jack',))
t2.start()
t3 = Thread(target=eat1,args=('alex',))
t3.start()
# tom拿到筷子了
# tom拿到面了
# tom可以吃面了
# marry拿到面了
# marry拿到筷子了
# marry可以吃面了
# jack拿到筷子了
# jack拿到面了
# jack可以吃面了
# alex拿到面了
# alex拿到筷子了
# alex可以吃面了 #Rlock解决死锁问题(更加简洁的写法):
from threading import RLock
from threading import Thread
def eat(name):
lock.acquire()
print('%s拿到筷子了'%name)
lock.acquire()
print('%s拿到面了'%name)
print('%s可以吃面了'%name)
lock.release()
lock.release() def eat1(name):
lock.acquire()
print('%s拿到面了'%name)
lock.acquire()
print('%s拿到筷子了'%name)
print('%s可以吃面了'%name)
lock.release()
lock.release() lock = RLock()
t = Thread(target=eat,args=('tom',))
t.start()
t1 = Thread(target=eat1,args=('marry',))
t1.start()
t2 = Thread(target=eat,args=('jack',))
t2.start()
t3 = Thread(target=eat1,args=('alex',))
t3.start()
day47-线程-锁和死锁的更多相关文章
- C# 线程锁Lock 死锁
使用lock场景 多线程环境中,不使用lock锁,会形成竞争条件,导致错误. 使用lock 锁 可以保证当有线程操作某个共享资源时,其他线程必须等待直到当前线程完成操作. 即是多线程环境,如果一个线程 ...
- python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池
0.承上 什么是线程? CPU调度的最小单位. 线程是进程的必要组成单位. 主线程: 程序开始运行的时候,就产生了一个主线进程来运行这个程序. 子线程: 是由主线程开启的其他线程. · 各线程之间的工 ...
- 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁
当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...
- python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)
什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: 一 from threading import Thread ...
- Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量
在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...
- GIL全局解释锁,死锁,信号量,event事件,线程queue,TCP服务端实现并发
一.GIL全局解释锁 在Cpython解释器才有GIL的概念,不是python的特点 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势. 1.GIL介绍 ...
- day36 joinablequeue、多线程理论、多线程的两种使用方式、守护线程、互斥锁、死锁、递归锁、信号量
1.joinablequeue队列 joinablequeue与queue一样,也是一种队列,其继承自queue,也有queue中的put 与get 方法,但是在joinablequeue中有自己的 ...
- 并发编程(五)——GIL全局解释器锁、死锁现象与递归锁、信号量、Event事件、线程queue
GIL.死锁现象与递归锁.信号量.Event事件.线程queue 一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多 ...
- TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q
TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务 ...
- Linux同步机制(一) - 线程锁
1 互斥锁 在线程实际运行过程中,我们经常需要多个线程保持同步. 这时可以用互斥锁来完成任务.互斥锁的使用过程中,主要有 pthread_mutex_init pthread_mutex_destor ...
随机推荐
- 读书笔记 - javascript 高级程序设计 - 第二章 在Html中使用JavaScript
1 <script>的6个属性 async 立即下载当前script标签的外部脚本 但不能影响别的 charset 没用了 defer 文档显示之后再执行脚本,只对外部脚本有效 lan ...
- java课程之团队开发冲刺阶段1.9
一.总结昨天进度 1.学习了简单的消息推送方法,并且能够使用进行每日定时推送 二.遇到的困难 1.在每日推送的过程中,程序必须被正常关闭,如果程序是被切到后天然后直接结束进程的话,每日推送的线程服务也 ...
- mysql5.7.21源码安装
1.下载安装包 MySQL 官方下载地址:https://dev.mysql.com/downloads/mysql/ MySQL 5.7官方安装文档:https://dev.mysql.com/d ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习:弹窗
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> ...
- 大数据攻城狮之进阶技能-Github的使用
引用百度百科中的介绍: github GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线 ...
- 微信公众号开发调用摄像头、拍摄或选择图片、OCR识别
一 .准备工作 <1> 域名认证准备工作 在需要调用摄像头的接口页面引入微信的js,具体地址为:(支持https):http://res.wx.qq.com/open/js/ ...
- 撤销上一次的commit
撤销上一次的commit git reset HEAD~ 如果是撤销所有的已经add的文件: git reset HEAD .
- JDK8新特性之stream
stream中有很多方法,讲一些常用的. 1.forEach(),遍历方法,很简单,对于一般的遍历可以替代for循环 List<String> strings = Arrays.asLis ...
- intellij idea安卓开发配置
1.java sdk 2.java ndk 3.gradle https://gradle.org/install/#manually 配置properties 删除根目录下android{} htt ...
- ZJNU 1244/1245 - 森哥数——高级
打表找规律吧…… 一定要记得每一步都得开long long 然后可以发现所有的森哥数每一位只可能是0,1,2,3 就可以想到最高O(3^9)的算法 枚举1e9之内的所有满足条件的数判断 枚举9位数,最 ...