#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-线程-锁和死锁的更多相关文章

  1. C# 线程锁Lock 死锁

    使用lock场景 多线程环境中,不使用lock锁,会形成竞争条件,导致错误. 使用lock 锁 可以保证当有线程操作某个共享资源时,其他线程必须等待直到当前线程完成操作. 即是多线程环境,如果一个线程 ...

  2. python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池

    0.承上 什么是线程? CPU调度的最小单位. 线程是进程的必要组成单位. 主线程: 程序开始运行的时候,就产生了一个主线进程来运行这个程序. 子线程: 是由主线程开启的其他线程. · 各线程之间的工 ...

  3. 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

    当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...

  4. python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)

    什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: 一 from threading import Thread ...

  5. Python之路(第四十四篇)线程同步锁、死锁、递归锁、信号量

    在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock ...

  6. GIL全局解释锁,死锁,信号量,event事件,线程queue,TCP服务端实现并发

    一.GIL全局解释锁 在Cpython解释器才有GIL的概念,不是python的特点 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势. 1.GIL介绍 ...

  7. day36 joinablequeue、多线程理论、多线程的两种使用方式、守护线程、互斥锁、死锁、递归锁、信号量

    1.joinablequeue队列 joinablequeue与queue一样,也是一种队列,其继承自queue,也有queue中的put 与get 方法,但是在joinablequeue中有自己的 ...

  8. 并发编程(五)——GIL全局解释器锁、死锁现象与递归锁、信号量、Event事件、线程queue

    GIL.死锁现象与递归锁.信号量.Event事件.线程queue 一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多 ...

  9. TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q

    TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务 ...

  10. Linux同步机制(一) - 线程锁

    1 互斥锁 在线程实际运行过程中,我们经常需要多个线程保持同步. 这时可以用互斥锁来完成任务.互斥锁的使用过程中,主要有 pthread_mutex_init pthread_mutex_destor ...

随机推荐

  1. PyGame快速入门

    pygame 快速入门 目标 项目准备 使用 pygame 创建图形窗口 理解 图像 并实现图像绘制 理解 游戏循环 和 游戏时钟 理解 精灵 和 精灵组 项目准备 新建 飞机大战 项目 新建一个 h ...

  2. HTML 回到顶部 浮动

    回到顶部 <div id="FloatDIV" style="position: absolute; top: 0px; z-index: 9999; backgr ...

  3. ftp限制

    /etc/hosts.deny /etc/vsftpd/user_list 从2.3.5之后,vsftpd增强了安全检查,如果用户被限定在了其主目录下,则该用户的主目录不能再具有写权限了!如果检查发现 ...

  4. 20个GitHub最热门的Java开源项目:文档、框架、工具

    专注于Java领域优质技术,欢迎关注 文章来源:JavaGuide 以下涉及到的数据统计,数据来源:https://github.com/trending/java?since=monthly[1] ...

  5. MVC——EF 回顾总结

    回顾一下MVC的知识点. 其实开始 我在学校的知识对MVC 还是很模糊的一个概念.只是记得结合EasyUI 增删改查 和分页,代码都是模糊的 进过这段时间的学习,让我对MVC 有了一个很清楚的认识. ...

  6. gcd--最大公因数

    求两个数的最大公倍数 考完五校的第一天,在家补视频ing,简单来说的话就是给了两个数A,B 假设他们两个的最大公倍数为d,那么A=X*d,B=Y*d gcd就是把一直gcd(B%A,A)不断更新,其中 ...

  7. springCloud 常用组件总结

    本文浅谈只是对我自己初期认识这spring cloud的一个笔记. 微服务是一种架构风格和一种应对业务的架构策略.实现这种的技术方式很多.本文主要说spring cloud. spring cloud ...

  8. Activiti工作流的入门介绍

    一.activiti介绍 Activiti5是一个 业务流程管理(BPM)框架,它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流程语言框架.Activiti基于Ap ...

  9. 试验指标|试验单位|均方|随机模型|固定模型|字母标记法|LSR|q检验|LSD|重复值|弥补缺失数据|可加性|平方根转换|对数转换|反正弦转化

    第五章 方差分析 试验指标是什么? 就是统计的测量值,eg:身高体重 试验单位( experimental unit )是什么? 实验载体,比如一只小白鼠 均方是什么? 就是方差 随机模型的τ有何特点 ...

  10. idea中maven项目依赖jar一直标红线

    网上maven仓库中无法下载某些jar包,这时候就需要手动下载,并导入maven, 导入命令demo: mvn install:install-file -DgroupId=javax.media - ...