#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. [转]Log4j使用总结

    Log4j使用总结   一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器. ...

  2. (转)mysql语句

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...

  3. zabbix添加主机步骤

    创建主机 配置基本信息 配置好后点击添加即可: [root@localhost opt]# systemctl start zabbix-agent [root@localhost opt]# net ...

  4. CSS 选择器权重计算规则(转)

    其实,CSS有自己的优先级计算公式,而不仅仅是行间>内部>外部样式:ID>class>元素. 一.样式类型 1.行间 <h1 style="font-size: ...

  5. vzray上网教程

    1.首先按照之前的教程在chrome里安装插件-Proxy-SwitchyOmega-Chromium-2.5.15 2.打开  vzray-v3.11-windows-64,打开 3.在chrome ...

  6. 201604-2 俄罗斯方块 Java

    大家谁能帮我看看是哪里不对,提交到系统中是0分,在Eclipse中可以得出例子中的结果 思路: 题目中有两个关键点:如何模拟下落的过程,如何判断方块下落在哪里停止. 在数据的存储上,需要保存整个&qu ...

  7. 吴裕雄--天生自然Linux操作系统:Linux 文件与目录管理

    Linux的目录结构为树状结构,最顶级的目录为根目录 /. 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们. 绝对路径: 路径的写法,由根目录 / 写起,例如: /usr/share/ ...

  8. Android音视频处理之基于MediaCodec合并音视频

    Android提供了一个MediaExtractor类,可以用来分离容器中的视频track和音频track,下面的例子展示了使用MediaExtractor和MediaMuxer来实现视频的换音: p ...

  9. Django_JavaScript

    JavaScript是什么 JavaScript是一种运行在客户端(浏览器)的编程语言,用来给网页添加动态功能. JavaScript的作用 最初目的 为了处理表单的验证操作 现在广泛的应用场景 网页 ...

  10. 笔记本安装SSD固态硬盘详细的优化设置

    现在好多笔记本.台式机都加上固态硬盘了,固态硬盘的优势大家应该都有所了解了,在此略写一下固态硬盘优势:  1.启动快,没有电机加速旋转的过程:  2.不用磁头,快速随机读取,读延迟极小:  3.相对固 ...