(day31) Event+协程+进程/线程池
目录
昨日回顾
GIL全局解释器锁
- 本质上是互斥锁
- Cpython才有的
- 同一个进程下开启多个线程,让并发变成串行,保证线程安全
计算密集型和IO密集型
计算密集型
使用多进程
IO密集型
使用多线程
死锁现象
两个锁在两个或多个线程或进程中被相互调用,从而陷入相互等待的现象
递归锁
解决死锁问题,相当于串在一起的锁,只有在递归锁的引用计数为0 ,才能被使用
信号量
相当于锁店,设置多少个就能被多少个线程或进程使用
线程队列
FOFI队列
先进先出
LIFO队列
后进先出
优先级队列
按照从左到右,根据数字/acsii大小,越小,优先级越高
今日内容
Event事件
控制线程的执行,由一些线程去控制另一些线程
当Event对象为False时,该线程会被阻塞,直至Event对象为真,相当于红绿灯的作用
isSet():返回Event对象的状态
wait():判断Event对象的状态,若为Flase,则阻塞
Set():设置Event对象为Ture
clear():恢复Event对象为False
from threading import Event
from threading import Thread
import time
e = Event()
def light():
print('红灯亮')
time.sleep(5)
print('绿灯亮')
e.set()
def car():
print('等红灯中...')
e.wait()
print('车辆加速中')
t = Thread(target=light)
t.start()
for i in range(20):
a = Thread(target=car)
a.start()
线程池与进程池
- 进程池和线程池是用来控制当前程序允许创建的进程或线程的数量
- 保证在硬件允许的范围内创建进程/线程的数量
异步提交和回调函数
可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,并接收任务的返回值当作参数,该函数称为回调函数
ProcessPoolExecutor(5) # 5代表只能开启5个进程
ProcessPoolExecutor() # 默认以CPU的个数限制进程数
ThreadPoolExecutor() # 默认以CPU个数 * 5 限制线程数
pool.shutdown() # 会让所有线程池的任务结束后,才往下执行代码
pool.submit('传函数地址') # 异步提交任务
pool.submit('传函数地址').add_done_callback('回调函数地址') # 回调函数
import time
# from concurrent.futures import ProcessPoolExecutor
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(5)
def task(res):
print('线程任务开始')
time.sleep(1)
print('线程任务结束')
return res
def call_back(res):
res1 = res.result()
print(res1)
for i in range(5):
pool.submit(task,i).add_done_callback(call_back)
协程
协程:在单线程下实现并发,不是操作系统资源
通过手动模拟遇到IO切换,欺骗操作系统误以为没有进程IO操作,从而实现在程序层面的并发( 切换+保存状态)
- 优点:IO密集型情况下,会提高效率
缺点:若在计算密集型的情况下,来回切换,反而效率更低
yiled
无法检测IO,无法实现遇到IO自动切换
# 串行执行
import time
def func1():
for i in range(10000000):
i+1
def func2():
for i in range(10000000):
i+1
start = time.time()
func1()
func2()
stop = time.time()
print(stop - start) # 0.8930509090423584
# 验证计算密集型的情况下效率更低: # 1.4250171184539795
# 基于yield并发执行
import time
def func1():
while True:
10000000+1
yield
def func2():
# g生成器对象
g = func1()
for i in range(10000000):
time.sleep(100) # 模拟IO,yield并不会捕捉到并自动切换
i+1
next(g)
start = time.time()
func2()
stop = time.time()
print(stop-start)
gevent模块
第三方模块,可以监听IO操作,并实现切换 + 保存状态
from gevent import spawn,joinall # 用于做切换 + 保存状态
from gevent import monkey # 可以监听该程序下所有的IO操作
monkey.patch_all()
import time
def func1():
print('1')
time.sleep(1)
def func2():
print('2')
time.sleep(2)
def func3():
print('3')
time.sleep(3)
start = time.time()
s1=spawn(func1)
s2=spawn(func2)
s3=spawn(func3)
# 必须传序列类型
joinall((s1,s2,s3))
end = time.time()
print(end - start)
(day31) Event+协程+进程/线程池的更多相关文章
- 并发编程中死锁、递归锁、进程/线程池、协程TCP服务器并发等知识点
1.死锁 定义; 类似两个人分别被囚禁在两间房子里,A手上拿着的是B囚禁房间的钥匙,而B拿着A的钥匙,两个人都没法出去,没法给对方开锁,进而造成死锁现象.具体例子代码如下: # -*-coding:u ...
- 并发编程(六)--进程/线程池、协程、gevent第三方库
一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上百个或上千个,手动创建就较为繁琐,这时就可 ...
- 并发编程(六)——进程/线程池、协程、gevent第三方库
进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...
- day37协程与线程套接字通讯
协程与线程套接字通讯基于多线程实现套接字服务端支持并发,服务端 from socket import * from threading import Thread def comunicate(con ...
- unity3D中协程和线程混合
这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子: 大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了 ...
- Python学习---线程/协程/进程学习 1220【all】
Python学习---线程基础学习 Python学习---线程锁/信号量/条件变量同步1221 Python学习---同步条件event/队列queue1223 Python学习---进程 1225 ...
- I/O多路复用、协程、线程、进程
select注册fd,阻塞,当有fd状态改变时返回,确认对应的fd,做下一步处理.简单来说就是先注册,注册完后休眠并设置一个定时器醒来查看,有事件就通知来取,进行后续动作,没事件就继续睡,再设闹钟.用 ...
- 多任务-python实现-进程,协程,线程总结(2.1.16)
@ 目录 1.类比 2.总结 关于作者 1.类比 一个生产玩具的工厂: 一个生产线成为一个进程,一个生产线有多个工人,所以工人为线程 单进程-多线程:一条生产线,多个工人 多进程-多线程:多条生产线, ...
- 用Swoole4 打造高并发的PHP协程Mysql连接池
码云代码仓库:https://gitee.com/tanjiajun/MysqlPool 代码仓库:https://github.com/asbectJ/swoole4.git 前言 在写这篇文章之前 ...
随机推荐
- kafka报错:Invalid message size: 0
现象 1.kafka topic 部分分区积压 2.问题kafka 节点上一直报错:java.lang.IllegalStateException: Invalid message size: 0 [ ...
- Roman and Browser-罗曼的浏览器 CodeForce1100A 暴力
题目链接:Roman and Browser 题目原文 This morning, Roman woke up and opened the browser with
- wait()与notify()
一,前言 简单画了一下线程的流程图,只是一个大概.如图所示,线程有多种状态,那么不同状态之间是如何切换的,下面主要总结关于wait()和notify()的使用. 二,wait() wait ...
- Spring 梳理 - filter、interceptor、aop实现与区别 -第二篇
spring mvc中的Interceptor可以理解为是Spring MVC框架对AOP的一种实现方式.一般简单的功能又是通用的,每个请求都要去处理的,比如判断token是否失效可以使用spring ...
- Java之字符流读写文件、文件的拷贝
字符流读数据 – 按单个字符读取 创建字符流读文件对象: Reader reader = new FileReader("readme.txt"); 调用方法读取数据: int d ...
- ajax跨域访问数据
通过json发送和接受数据,数据以json的格式在服务器端和前台进行传递,什么是json数据?这里就不进行详细阐述,轻自行百度解决. 在html5 中利用ajax 异步请求时,会遇到跨域的问题,如果域 ...
- Yii2搭建后台并实现rbac权限控制完整实例教程
.安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/config/main-local.php 实际 ...
- Python集训营45天—Day08 (文件操作)
目录 1. 文件操作介绍 2. 文件的读写 2.1 文本文件 2.2 二进制文件 2.3 JSON文件 3. 文件的定位,重命名和删除 4. 文件夹的相关操作 1. 文件操作介绍 大家应该听说过一句话 ...
- 针对永久不过期的key 批量设置过期时间
问题需求: redis内存暴增,后来发现有很多设置永久不过期. 解决:查找出来之后针对前缀批量设置过期时间 (过期时间与开发沟通 保证服务不受影响) 来源于网上杨一的代码 正好解决了我遇到的问题 在这 ...
- mfc CString 转 char *
做界面时遇到需要从界面编辑框接受输入字符(用户名,密码之类),然后转为char *类型交给程序处理,记录一下找到的方法,主要参考https://blog.csdn.net/neverup_/artic ...