python Event事件、进程池与线程池、协程解析


Posted in Python onOctober 25, 2019

Event事件

用来控制线程的执行

出现e.wait(),就会把这个线程设置为False,就不能执行这个任务;

只要有一个线程出现e.set(),就会告诉Event对象,把有e.wait的用户全部改为True,剩余的任务就会立马去执行。由一些线程去控制另一些线程,中间通过Event。

from threading import Event
from threading import Thread
import time
# 调用Event实例化出对象
e = Event()
#
# # 若该方法出现在任务中,则为False,阻塞
# e.wait() # False
# # 若该方法出现在任务中,则将其他线程的False改为True,进入就绪态和运行态
# e.set() # True
def light():
 print('红灯亮...')
 time.sleep(5)
 # 应该发出信号,告诉其他线程准备执行
 e.set() # 将car中的False变为True
 print('绿灯亮...')
def car(name):
 print('正在等红灯...')
 # 让所有汽车任务进入阻塞态
 e.wait() # False
 print(f'{name}正在加速飘逸...')
# 让一个light线程控制多个car线程
t = Thread(target=light)
t.start()

for i in range(10):
 t = Thread(target=car, args=(f'汽车{i}号', ))
 t.start()

进程池与线程池

进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量

作用:保证在硬件允许的范围内创建(进程/线程)的数量

线程池使用一:

from concurrent.futures import ThreadPoolExecutor
import time
pool = ThreadPoolExecutor(5) # 5代表只能开启5个进程, 不加默认使用cpu的进程数
# ThreadPoolExecutor(5) # 5代表只能开启5个线程
# pool.submit() #异步提交任务, 括号里传函数地址
def task():
 print('线程任务开始了...')
 time.sleep(1)
 print('线程任务结束了...')
for line in range(5):
 pool.submit(task)

使用二:

from concurrent.futures import ThreadPoolExecutor
import time

pool = ThreadPoolExecutor(5) # 5代表只能开启5个进程, 不加默认使用cpu的进程数

# ThreadPoolExecutor(5) # 5代表只能开启5个线程
# pool.submit() #异步提交任务, 括号里传函数地址
def task():
 print('线程任务开始了...')
 time.sleep(1)
 print('线程任务结束了...')
 return 123
# 回调函数
def call_back(res):
 print(type(res))
 res2 = res.result() # 注意:赋值操作不要与接收的res同名
 print(res2)
for line in range(5):
 pool.submit(task).add_done_callback(call_back)

pool.shutdown() 会让所有线程池的任务结束后,才往下执行代码

多线程爬取梨视频

利用requests模块,封装底层socket套接字

  • 主页中获取所有视频id号,拼接视频详情页url
  • 在视频详情页中获取真实视频url srcUrl=
  • 往真实视频url地址发送请求获取 视频 二进制数据
  • 最后把视频二进制数据保存到本地

协程

  • 进程: 资源单位
  • 线程: 执行单位
  • 协程: 在单线程下实现并发

注意: 协程不是操作系统资源,目的是让单线程实现并发

协程目的

  • 操作系统:使用多道技术,切换 + 保存状态,一个是遇到IO, 另一个是CPU执行时间过长
  • 协程:通过手动模拟操作系统 “多道计数”, 实现 切换 + 保存状态
    • 手动实现,遇到IO切换,欺骗操作系统误以为没有IO操作
    • 单线程时,遇到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) # 1.0312113761901855


# 基于yield实现并发 在计算密集型的情况下效率更低

def func1():
 while True:
  10000000+1
  yield

def func2():
 g = func1()
 for i in range(10000000):
  i+1
  next(g) # 每次执行next相当于切换到func1下面
start = time.time()
func2()
stop = time.time()
print(stop - start) # 1.3294126987457275

gevent

gevent是一个第三方模块,可以帮你监听IO操作,并切换

使用gevent的目的:在单线程下实现,遇到IO就会 保存状态 + 切换

import time
from gevent import monkey

monkey.patch_all() # 可以监听该程序下所有的IO操作
from gevent import spawn, joinall # 用于做切换 + 保存状态
def func1():
 print('1')
 time.sleep(1) # IO操作
def func2():
 print('2')
 time.sleep(3)
def func3():
 print('3')
 time.sleep(5)
start = time.time()
s1 = spawn(func1)
s2 = spawn(func2)
s3 = spawn(func3)

s1.join() # 发送信号,相当于等待自己(在单线程的情况下)
s2.join()
s3.join()

# joinall((s1, s2, s3)) # 一个个执行很麻烦,可以用joinall把这些全部装进去

end = time.time()
print(end - start) # 5.006161451339722

TCP服务端socket套接字实现协程

服务端:

from gevent import monkey
from gevent import spawn
import socket

monkey.patch_all()
server = socket.socket()
server.bind(('127.0.0.1', 9999))
server.listen(5)

def task(conn):
 while True:
  try:
   data = conn.recv(1024)
   if len(data) == 0:
    break
   print(data.decode('utf-8'))
   send_data = data.upper()
   conn.send(send_data)

  except Exception:
   break
 conn.close()
def server2():
 while True:
  conn, addr = server.accept()
  print(addr)
  spawn(task, conn)
if __name__ == '__main__':
 s = spawn(server2)
 s.join()

客户端:

import socket
from threading import Thread, current_thread

def client():
 client = socket.socket()
 client.connect(('127.0.0.1', 9999))

 number = 0
 while True:
  send_data = f'{current_thread().name} {number}'
  client.send(send_data.encode('utf-8'))

  data = client.recv(1024)
  print(data.decode('utf-8'))
  number += 1


for i in range(400):
 t = Thread(target=client)
 t.start()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python使用smtplib模块通过gmail实现邮件发送的方法
May 08 Python
Python实现给qq邮箱发送邮件的方法
May 28 Python
python使用psutil模块获取系统状态
Aug 27 Python
Python发送http请求解析返回json的实例
Mar 26 Python
python爬虫库scrapy简单使用实例详解
Feb 10 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
Apr 07 Python
.img/.hdr格式转.nii格式的操作
Jul 01 Python
Python 实现国产SM3加密算法的示例代码
Sep 21 Python
Python 利用argparse模块实现脚本命令行参数解析
Dec 28 Python
python实现web邮箱扫描的示例(附源码)
Mar 30 Python
基于Pygame实现简单的贪吃蛇游戏
Dec 06 Python
python中pd.cut()与pd.qcut()的对比及示例
Jun 16 Python
python实现简单银行管理系统
Oct 25 #Python
Python银行系统实战源码
Oct 25 #Python
python实现银行管理系统
Oct 25 #Python
Django视图扩展类知识点详解
Oct 25 #Python
Python装饰器使用你可能不知道的几种姿势
Oct 25 #Python
win7下 python3.6 安装opencv 和 opencv-contrib-python解决 cv2.xfeatures2d.SIFT_create() 的问题
Oct 24 #Python
Python下应用opencv 实现人脸检测功能
Oct 24 #Python
You might like
php上传图片到指定位置路径保存到数据库的具体实现
2013/12/30 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
php实现推荐功能的简单实例
2019/09/29 PHP
JS OOP包机制,类创建的方法定义
2009/11/02 Javascript
ExtJs 3.1 XmlTreeLoader Example Error
2010/02/09 Javascript
js鼠标左右键 键盘值小结
2010/06/11 Javascript
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
详解js中构造流程图的核心技术JsPlumb(2)
2015/12/08 Javascript
javascript设计模式之module(模块)模式
2016/08/19 Javascript
浅析JavaScript中作用域和作用域链
2016/12/06 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
Vue.js的动态组件模板的实现
2018/11/26 Javascript
js实现自定义滚动条的示例
2020/10/27 Javascript
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
python使用webdriver爬取微信公众号
2018/08/31 Python
python多线程高级锁condition简单用法示例
2019/11/07 Python
django框架auth模块用法实例详解
2019/12/10 Python
win10下opencv-python特定版本手动安装与pip自动安装教程
2020/03/05 Python
记录一下scrapy中settings的一些配置小结
2020/09/28 Python
html5 touch事件实现页面上下滑动效果【附代码】
2016/03/10 HTML / CSS
详解使用canvas保存网页为pdf文件支持跨域
2018/11/23 HTML / CSS
美国最大和最受信任的二手轮胎商店:Bestusedtires.com
2020/06/02 全球购物
介绍一下如何优化MySql
2016/12/20 面试题
中医药大学市场营销专业自荐信
2013/09/29 职场文书
会计自荐书
2013/12/02 职场文书
优秀护士先进事迹
2014/05/08 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
施工安全协议书范本
2014/09/26 职场文书
2014年银行个人工作总结
2014/12/05 职场文书
2014年卫生保健工作总结
2014/12/08 职场文书
民间借贷借条如何写
2015/05/26 职场文书
高中物理教学反思
2016/02/19 职场文书