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 ...
随机推荐
- Codeforces 1291A - Even But Not Even
题目大意: 给定一个字符串数字(很大) 问能不能删除一些数字(或者不删除) 使得剩余的数字各位数相加是偶数,但是这整个数字是个奇数 解题思路: 统计字符串中单个数字奇数的个数 分情况 个数为0或者1时 ...
- Vue编程式路由跳转传递参数
Vue 有时在路由跳转时需要用到一些原页面里的数据,用以下方法: 1.在跳转页的方法里写下query参数 TableChange(scope){ this.$router.push({ path:'d ...
- 用Pandas Dataframe支撑起多只金融产品股票的数据内部形态
3. 如果同时拿一个板块股票的收市价和成交额 前一篇说到,用大盘指数,如恒生指数,上证,深证,这些重要的大盘指数来做Dataframe主键,那麽如果是同时拿一个板块股票的收市价和成交额,可以怎样操作呢 ...
- 小程序调用wx.chooseLocation接口的时候无法获取权限(ios)
ios手机小程序调用wx.chooseLocation接口的时候,获取权限的时候报authorize:fail:require permission desc这样子的错误,这是由于苹果的安全机制导致需 ...
- 四、python杂项
一.pycharm单行和多行注释快捷键 多行注释就一个组合键:选中+Ctrl+/
- 题解 P1317 【低洼地】
题目 这题挺简单的,没必要用数组 [分析] 需要判断的是低洼地的数量 通过对题目中图进行分析,显然可以发现低洼地的定义: 若数组中存在一个数值相同的连续区间,这个区间端点外相邻两点的数值都大于该区间的 ...
- svnkit-常用api
0.功能列表 svnkit功能列表 1.递归获取指定目录下目录和文件,以树形展示[svn Update] 2.获取指定文件和属性(版本号.作者.日期.文件类型) 3.获取指定文件或目录的历史记录(版本 ...
- SQL注入——报错注入
0x00 背景 SQL注入长期位于OWASP TOP10 榜首,对Web 安全有着很大的影响,黑客们往往在注入过程中根据错误回显进行判断,但是现在非常多的Web程序没有正常的错误回显,这样就需要我们利 ...
- Django模型基础——(二)
上篇博客主要讲了django中对数据库的增删改查,下面深入再讲解下对数据库的操作. 常用的查询方法 下面以表名为User为例 User.object.first() :返回表中第一条数据 User.o ...
- git 知识罗列
git pull is basically a shortcut for two operations: git fetch which downloads the history from the ...