Day 42 协程. IO 并发
一、什么是协程?
是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
协程相比于线程切换效率更快了.
本质是线程
能够在多个任务之间切换来节省一些IO时间.
协程中任务之间的切换时间开销要远远小于进程线程之间的切换.
真正的协程模块就是使用greenlet完成切换的.
进程和协程的任务切换由操作系统完成.
协程任务之间的切换由程序完成.
协程任务之间的切换由程序代码完成 , 只有遇到协程模块能识别的io操作的时候程序才会进行任务切换,实现并发的效果。
协程:
能够在一个线程中实现并发效果的概念.
能够规避一些任务中的IO操作.
在任务的执行过程中,检测到IO就切换到其他任务.
在两个任务之间来回切换数据(简单的协程的概念)
# import time
# def consumer():
# while True:
# x = yield
# time.sleep(1)
# print('处理了数据 :',x)
#
# def producer():
# c = consumer()#生成一个生成器对象
# next(c) #每次next返回一个值
# for i in range(10):
# time.sleep(1)
# print('生产了数据 :',i)
# c.send(i)
# producer()
输出结果:虽然实现了切换,但是没有节约IO时间.
D:\PycharmProjects\test\venv\Scripts\python.exe D:/parcharm/42.py
生产了数据 : 0
处理了数据 : 0
生产了数据 : 1
处理了数据 : 1
生产了数据 : 2
处理了数据 : 2
生产了数据 : 3
处理了数据 : 3
生产了数据 : 4
处理了数据 : 4
生产了数据 : 5
处理了数据 : 5
生产了数据 : 6
处理了数据 : 6
生产了数据 : 7
处理了数据 : 7
生产了数据 : 8
处理了数据 : 8
生产了数据 : 9
处理了数据 : 9
二 、安装 gevent和greenlet

查看安装状态

真正的协程模块就是使用greenlet完成的切换
from greenlet import greenlet
def eat():
print("吃开始")
g2.switch()
print("吃完了")
g2.switch()
def play():
print("开始玩")
g1.switch()
print('玩完了')
g1 =greenlet(eat)
g2 =greenlet(play)
g1.switch()
打印结果:
D:\PycharmProjects\test\venv\Scripts\python.exe D:/parcharm/44.py
吃开始
开始玩
吃完了
玩完了

协程能够在一个线程中实现并发效果的概念。
能够规避一些任务中的IO操作
在任务的执行过程中,检测到IO就切换到其他的任务.
三、爬虫的例子(正则有基础.)
请求过程中的IO等待
import requests #需要pip安装的。
from urllib.request import urlopen#内置的模块
url='http://www.baidu.com'
res1 =urlopen(url)
res2 = requests.get(url)
print(res1)
print(res2) print(res1.read().decode('utf-8'))# 有格式的
print(res2.content.decode('utf-8'))#无格式的。
爬虫 (结果是一起显示出来的。)
gevent 用在爬虫和socket的编程中会用的到.
gevent是python的一个并发框架,以微线程greenlet为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效.而且其中有个monkey类,
将现有基于Python线程直接转化为greenlet(类似于打patch).他和线程框架性能比高大概4倍(看下图,是gevent和paste的对比):
from gevent import monkey;monkey.patch_all()
import gevent
from urllib.request import urlopen
def get_url(url):
response = urlopen(url)
content = response.read().decode('utf-8')
return len(content) g1 =gevent.spawn(get_url,'http://www.baidu.com')
g2 =gevent.spawn(get_url,'http://www.sohu.com')
g3 =gevent.spawn(get_url,'http://www.hao123.com')
g4 =gevent.spawn(get_url,'http://www.cnblog.com')
g5 =gevent.spawn(get_url,'http://www.cnblog.com')
gevent.joinall([g1,g2,g3,g4,g5])
print(g1.value)
print(g2.value)
print(g3.value)
print(g4.value)
print(g5.value)
打印结果
D:\PycharmProjects\test\venv\Scripts\python.exe D:/parcharm/44.py
114439
185037
523375
1887
1887
协程实现socket的案例
协程间的切换是代码级别的,
线程间切换时操作系统级别的。
Server端
from gevent import monkey;monkey.patch_all()
import socket
import gevent
def talk(conn):
conn.send(b'hello')
print(conn.recv(1024).decode('utf-8'))
conn.close() sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
while True:
conn,addr = sk.accept()
gevent.spawn(talk,conn)
sk.close()
client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
print(sk.recv(1024))
msg = input('>>>').encode('utf-8')
sk.send(msg)
sk.close()
四 IO模型.
blocking IO 阻塞IO
nonblocking IO 非阻塞IO
IO multiplexing IO 多路复用
asynchronous IO 异步 IO
Blocking IO 阻塞IO
同步:同步提交一个任务之后要等待这个任务执行完毕.
异步只管提交任务,







Day 42 协程. IO 并发的更多相关文章
- 协程IO多路复用
协程:单线程下实现并发并发:伪并行,遇到IO就切换,单核下多个任务之间切换执行,给你的效果就是貌似你的几个程序在同时执行.提高效率任务切换 + 保存状态并行:多核cpu,真正的同时执行串行:一个任务执 ...
- 理解Go协程与并发
协程 Go语言里创建一个协程很简单,使用go关键字就可以让一个普通方法协程化: package main import ( "fmt" "time" ) fun ...
- day 35 协程 IO多路复用
0.基于socket发送Http请求 import socket import requests # 方式一 ret = requests.get('https://www.baidu.com/s?w ...
- 数据库 tcp协程实现并发 回调函数
数据库 tcp协程实现并发 回顾 一.回顾 进程池,线程池,回调函数 # from gevent import monkey;monkey.patch_all() #补丁 from gevent im ...
- 理解Go协程与并发(转)
理解Go协程与并发 协程 Go语言里创建一个协程很简单,使用go关键字就可以让一个普通方法协程化: Copy package main import ( "fmt" " ...
- 11.python3标准库--使用进程、线程和协程提供并发性
''' python提供了一些复杂的工具用于管理使用进程和线程的并发操作. 通过应用这些计数,使用这些模块并发地运行作业的各个部分,即便是一些相当简单的程序也可以更快的运行 subprocess提供了 ...
- 05网络并发 ( GIL+进程池与线程池+协程+IO模型 )
目录 05 网络并发 05 网络并发
- 协程+IO切换实现并发
from gevent import monkey # 以后代码中遇到IO都会自动执行greenlet的switch进行切换 monkey.patch_all() import requests im ...
- Python学习笔记整理总结【网络编程】【线程/进程/协程/IO多路模型/select/poll/epoll/selector】
一.socket(单链接) 1.socket:应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socke ...
随机推荐
- 轮播图jQuery
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux indent命令
一.简介 indent可辨识C的原始代码文件,并加以格式化,以方便程序设计师阅读. 二.选项 http://www.cnblogs.com/xuxm2007/archive/2011/11/03/22 ...
- Codeforces 608B. Hamming Distance Sum 模拟
B. Hamming Distance Sum time limit per test: 2 seconds memory limit per test:256 megabytes input: st ...
- laravel的函数asset()、url()
1.asset():用于引入静态文件,如 css/JavaScript/images,文件必须存放在public文件目录下 src="{{ asset('home') }}/images/t ...
- [Eclipse]Eclipse里对XML进行注释的快捷键
eclipse中编辑java或C/C++文件时,注释的快捷键均为 "CTRL + / ",编辑xml文件时,该快捷键无效. eclipse 针对 XML 注释:CTRL + SHI ...
- Java数据结构和算法(七)B+ 树
Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...
- "UX"将会是下一个Buzzword?
“用户体验非常重要”.“没有用户体验就没有产品”.“UX就是一切”.不知道从何时开始,用户体验(UX) 这个名词已经变得如此多见了,但是人们真正的认识.认清了什么是用户体验了吗?设计师们常挂在嘴边的用 ...
- 使用Application Center Test (ACT)来做压力测试 【转】
在我们完成了基于SPS2003的开发,实现了我们的具体应用以后,我们是不是就可以直接请用户来使用了呢?如果我这么做,那么有经验的开发人员一定会对此嗤之以鼻:居然连压力测试也不做!真是不想活了…… 呵呵 ...
- 2018.10.12 NOIP模拟 数据结构(线段树)
传送门 sb线段树题居然还卡常. 修改操作直接更新区间最小值和区间标记下传即可. 询问加起来最多5e65e65e6个数. 因此直接询问5e65e65e6次最小值就行了. 代码
- 2018.09.07 Amount of degrees(数位dp)
描述 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和. 例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意: 17 = 24+20, ...