05网络并发 ( GIL+进程池与线程池+协程+IO模型 )
并发编程
进程池与线程池基本使用
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time
import os
# 创建进程池与线程池
# pool = ThreadPoolExecutor(5) # 可以自定义线程数 也可以采用默认策略
pool = ProcessPoolExecutor(5) # 可以自定义线程数 也可以采用默认策略
# 定义一个任务
def task(n):
print(n, os.getpid())
time.sleep(2)
return '>>>:%s' % n ** 2
# 定义一个回调函数:异步提交完之后有结果自动调用该函数
def call_back(a):
print('异步回调函数:%s' % a.result())
# 朝线程池中提交任务
# obj_list = []
for i in range(20):
res = pool.submit(task, i).add_done_callback(call_back) # 异步提交
# obj_list.append(res)
"""
同步:提交完任务之后原地等待任务的返回结果 期间不做任何事
异步:提交完任务之后不愿地等待任务的返回结果 结果由异步回调机制自动反馈
"""
# 等待线程池中所有的任务执行完毕之后 再获取各自任务的结果
# pool.shutdown()
# for i in obj_list:
# print(i.result()) # 获取任务的执行结果 同步
在windows电脑中如果是进程池的使用也需要在__main__下面
协程理论与实操
进程
资源单位
线程
工作单位
协程
是程序员单方面意淫出来的名词>>>:单线程下实现并发
# CPU被剥夺的条件
1.程序长时间占用
2.程序进入IO操作
# 并发
切换+保存状态
以往学习的是:多个任务(进程、线程)来回切换
# 欺骗CPU的行为
单线程下我们如果能够自己检测IO操作并且自己实现代码层面的切换
那么对于CPU而言我们这个程序就没有IO操作,CPU会尽可能的被占用
"""代码层面"""
第三方gevent模块:能够自主监测IO行为并切换
from gevent import monkey;monkey.patch_all() # 固定代码格式加上之后才能检测所有的IO行为
from gevent import spawn
import time
def play(name):
print('%s play 1' % name)
time.sleep(5)
print('%s play 2' % name)
def eat(name):
print('%s eat 1' % name)
time.sleep(3)
print('%s eat 2' % name)
start = time.time()
# play('jason') # 正常的同步调用
# eat('jason') # 正常的同步调用
g1 = spawn(play, 'jason') # 异步提交
g2 = spawn(eat, 'jason') # 异步提交
g1.join()
g2.join() # 等待被监测的任务运行完毕
print('主', time.time() - start) # 单线程下实现并发,提升效率
协程实现TCP服务端并发的效果
# 并发效果:一个服务端可以同时服务多个客户端
import socket
from gevent import monkey;monkey.patch_all()
from gevent import spawn
def talk(sock):
while True:
try:
data = sock.recv(1024)
if len(data) == 0:break
print(data)
sock.send(data+b'hello baby!')
except ConnectionResetError as e:
print(e)
sock.close()
break
def servers():
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen()
while True:
sock, addr = server.accept()
spawn(talk,sock)
g1 = spawn(servers)
g1.join()
# 客户端开设几百个线程发消息即可
"""
最牛逼的情况:多进程下开设多线程 多线程下开设协程
我们以后可能自己动手写的不多 一般都是使用别人封装好的模块或框架
"""
IO模型简介
"""理论为主 代码实现大部分为伪代码(没有实际含义 仅为验证参考)"""
IO模型研究的主要是网络IO(linux系统)
# 基本关键字
同步(synchronous) 大部分情况下会采用缩写的形式 sync
异步(asynchronous) async
阻塞(blocking)
非阻塞(non-blocking)
# 研究的方向
Stevens在文章中一共比较了五种IO Model:
* blocking IO 阻塞IO
* nonblocking IO 非阻塞IO
* IO multiplexing IO多路复用
* signal driven IO 信号驱动IO
* asynchronous IO 异步IO
由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model
四种IO模型简介
# 1.阻塞IO
最为常见的一种IO模型 有两个等待的阶段(wait for data、copy data)
# 2.非阻塞IO
系统调用阶段变为了非阻塞(轮训) 有一个等待的阶段(copy data)
轮训的阶段是比较消耗资源的
# 3.多路复用IO
利用select或者epoll来监管多个程序 一旦某个程序需要的数据存在于内存中了 那么立刻通知该程序去取即可
# 4.异步IO
只需要发起一次系统调用 之后无需频繁发送 有结果并准备好之后会通过异步回调机制反馈给调用者
05网络并发 ( GIL+进程池与线程池+协程+IO模型 )的更多相关文章
- Flask 之分析线程和协程
目录 flask之分析线程和协程 01 思考:每个请求之间的关系 02 threading.local 03 通过字典自定义threading.local 04 通过setattr和getattr实现 ...
- 第三十八天 GIL 进程池与线程池
今日内容: 1.GIL 全局解释器锁 2.Cpython解释器并发效率验证 3.线程互斥锁和GIL对比 4.进程池与线程池 一.全局解释器锁 1.GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在 ...
- GIL锁、进程池与线程池
1.什么是GIL? 官方解释: ''' In CPython, the global interpreter lock, or GIL, is a mutex that prevents multip ...
- GIL锁、进程池与线程池、同步异步
GIL锁定义 GIL锁:Global Interpreter Lock 全局解释器 本质上是一把互斥锁 官方解释: 在CPython中,这个全局解释器锁,也称为GIL,是一个互斥锁,防止多个线程在同 ...
- GIL与普通互斥锁区别,死锁现象,信号量,event事件,进程池与线程池,协程
GIL与普通互斥锁区别 GIL锁和互斥锁的异同点 相同: 都是为了解决解释器中多个线程资源竞争的问题 异: 1.互斥锁是Python代码层面的锁,解决Python程序中多线程共享资源的问题(线程数据共 ...
- GIL,queue,进程池与线程池
GIL 1.什么是GIL(这是Cpython解释器) GIL本质就是一把互斥锁,既然是互斥锁,原理都是一样的,都是让多个并发线程同一时间只能有一个执行 即:有了GIL的存在,同一进程内的多个线程同一时 ...
- Python并发编程之进程池与线程池
一.进程池与线程池 python标准模块concurrent.futures(并发未来) 1.concurrent.futures模块是用来创建并行的任务,提供了更高级别的接口,为了异步执行调用 2. ...
- GIL解释锁及进程池和线程池
官方介绍 ''' 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple nati ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
随机推荐
- Flask_Flask-Mail邮件扩展(十三)
在开发过程中,很多应用程序都需要通过邮件提醒用户,Flask的扩展包Flask-Mail通过包装了Python内置的smtplib包,可以用在Flask程序中发送邮件. Flask-Mail连接到简单 ...
- java 方法 compareTo()的正确使用
总结:(1)如果比较的是数字 则结果大于则为1 等于则为0 小于则为-1(2)如果比较的是字符[串] 则按照从左到右排序找对应不一样的字符第一个字符, 然后将字符装对应的ASCLL码数字,做减法运算, ...
- NIO【同步非阻塞io模型】关于 NIO socket 的详细总结【Java客户端+Java服务端 + 业务层】【可以客户端间发消息】
1.前言 以前使用 websocket来实现双向通信,如今深入了解了 NIO 同步非阻塞io模型 , 优势是 处理效率很高,吞吐量巨大,能很快处理大文件,不仅可以 做 文件io操作, 还可以做sock ...
- python 读取配置文件ini ---ConfigParser
Python读取ini文件需要用到 ConfigParser 模块 关于ConfigParser模块的介绍详情请参照官网解释:https://docs.python.org/2.7/library/c ...
- redis的bind误区
对于Redis中bind的正确的理解是:bind:是绑定本机的IP地址,(准确的是:本机的网卡对应的IP地址,每一个网卡都有一个IP地址),而不是redis允许来自其他计算机的IP地址.如果指定了bi ...
- Chromium Windows Build
https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/windows_build_instructions.md ...
- 为什么char类型输入遇空格会结束,int类型必须要空格才能输出
char类型与int类型输入时的区别: 在C语言的规则中,规定了scanf函数在接收字符串时--遇到空格或回车就认为前面的输入已经完成且有效! 而对于int类型:表示整数,输入时需要用空格隔开,以确认 ...
- leetcode 46. 全排列 及 47. 全排列 II
46. 全排列 问题描述 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3 ...
- leetcode 233. 数字 1 的个数
问题描述 给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数. 示例: 输入: 13 输出: 6 解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 . 问 ...
- [源码分析] Facebook如何训练超大模型---(1)
[源码分析] Facebook如何训练超大模型---(1) 目录 [源码分析] Facebook如何训练超大模型---(1) 0x00 摘要 0x01 简介 1.1 FAIR & FSDP 1 ...