python 3.x 学习笔记17(协程以及I/O模式)
1.协程(微线程)
协程是一种用户态的轻量级线程。
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:
协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
2.greenlet模块
greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator
例子
from greenlet import greenlet def fun1():
print(6)
gar2.switch() #转换到gar2
print(58) def fun2():
print(54)
gar1.switch() gar1 = greenlet(fun1) #启动协程
gar2 = greenlet(fun2)
gar1.switch()
3.gevent模块
gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
import gevent def fun1():
print('第一次运行fun1')
gevent.sleep(2) #切换到fun2的gevent.sleep(1)这一步
print('第二次运行fun1')
def fun2():
print('第一次运行fun2')
gevent.sleep(1) #sleep时间没到继续切换到fun3的gevent.sleep(2)
print('第二次运行fun2')
def fun3():
print('第一次运行fun3')
gevent.sleep(2)
print('第二次运行fun3') gevent.joinall( [
gevent.spawn(fun1),
gevent.spawn(fun2),
gevent.spawn(fun3),
])
结果
第一次运行fun1
第一次运行fun2
第一次运行fun3
第二次运行fun2
第二次运行fun1
第二次运行fun3
4.gevent默认检测不了urllib的i/o操作
5.要异步操作爬虫,必须加上monkey.patch_all(),意思是把当前程序的所有的io操作单独做上标记
如
from urllib import request
import gevent,time
from gevent import monkey
monkey.patch_all() #把当前程序的所有的io操作单独做上标记
def f(url):
print('GET%s'%url)
resp = request.urlopen(url)
data = resp.read()
print('%d 数据接收来自%s.' % (len(data), url)) start_time = time.time()
gevent.joinall([
gevent.spawn(f, 'https://www.python.org/'),
gevent.spawn(f, 'https://www.baidu.com/'),
gevent.spawn(f, 'https://github.com/'),
])
print('总共时间:',time.time()-start_time)
6.事件驱动模型
目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
1). 有一个事件(消息)队列;
2. 鼠标按下时,往这个队列中增加一个点击事件(消息);
3). 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
4). 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;
7.事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。另外两种常见的编程范式是(单线程)同步以及多线程编程。
8.缓存 I/O
缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。
缓存 I/O 的缺点:
数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。
注释:此缓存 I/O 在linux环境下的I/O
详解:http://www.cnblogs.com/alex3714/articles/5876749.html
9.IO模式
阻塞 I/O(blocking IO)
非阻塞 I/O(nonblocking IO)
I/O 多路复用( IO multiplexing)
信号驱动 I/O( signal driven IO)
异步 I/O(asynchronous IO)
python 3.x 学习笔记17(协程以及I/O模式)的更多相关文章
- python自动化开发学习 进程, 线程, 协程
python自动化开发学习 进程, 线程, 协程 前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- Python之线程、进程和协程
python之线程.进程和协程 目录: 引言 一.线程 1.1 普通的多线程 1.2 自定义线程类 1.3 线程锁 1.3.1 未使用锁 1.3.2 普通锁Lock和RLock 1.3.3 信号量(S ...
- python网络爬虫学习笔记
python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...
- Python Built-in Function 学习笔记
Python Built-in Function 学习笔记 1. 匿名函数 1.1 什么是匿名函数 python允许使用lambda来创建一个匿名函数,匿名是因为他不需要以标准的方式来声明,比如def ...
- Requests:Python HTTP Module学习笔记(一)(转)
Requests:Python HTTP Module学习笔记(一) 在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标 ...
- Ext.Net学习笔记17:Ext.Net GridPanel Selection
Ext.Net学习笔记17:Ext.Net GridPanel Selection 接下来是Ext.Net的GridPanel的另外一个功能:选择. 我们在GridPanel最开始的用法中已经见识过如 ...
- SQL反模式学习笔记17 全文搜索
目标:全文搜索 使用SQL搜索关键字,同时保证快速和精确,依旧是相当地困难. SQL的一个基本原理(以及SQL所继承的关系原理)就是一列中的单个数据是原子性的. 反模式:模式匹配 使用Like 或者正 ...
- python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用
python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...
随机推荐
- Ruby. Vs . Python
前言:从语言的本质上来分析,我对Ruby持反对态度,毕竟语言是为了交流,在表达的效率层面为了正确性必须适当放弃复杂性.且有句老话说的好,Ruby In Rails 才是语言,而Ruby只是这个语言的工 ...
- java学习笔记5——String类常用方法
1.字符串长度计算: int i = String1.length(); 2.字符串比较:1) equals()和equalsIgnoreCase //比较两个字符串对象的实体是否相同,相同输出tru ...
- (转)微服务架构 互联网保险O2O平台微服务架构设计
http://www.cnblogs.com/Leo_wl/p/5049722.html 微服务架构 互联网保险O2O平台微服务架构设计 关于架构,笔者认为并不是越复杂越好,而是相反,简单就是硬道理也 ...
- 文件系统VFS数据结构(超级块 inode dentry file)(收集整理)
Linux虚拟文件系统四大对象: 1)超级块(super block) 2)索引节点(inode) 3)目录项(dentry) 4)文件对象(file) 一个进程在对一个文件进行操作时各种对象的引用过 ...
- 动态给某一个元素添加active
<li class="one_data" data-id='+ navGroup.self_first_nav[i].id +'><a href='+ navG ...
- websocket 进阶!netty框架实现websocket达到高并发
引言: 在前面两篇文章中,我们对原生websocket进行了了解,且用demo来简单的讲解了其用法.但是在实际项目中,那样的用法是不可取的,理由是tomcat对高并发的支持不怎么好,特别是tomcat ...
- BZOJ 1264: [AHOI2006]基因匹配Match DP_树状数组_LCS转LIS
由于有重复数字,我们以一个序列为基准,另一个序列以第一个序列每个数所在下标为这个序列每个数对应的值. 注意的是,拆值的时候按照在第一个序列中的位置从大到小排,强制只能选一个. 最后跑一边最长上升子序列 ...
- 如何添加删除子网卡eth0:1(linux案例)
这种方法实现了单网卡多IP,我的系统是centos7的,如何添加删除子网卡IP详细请看下面操作例子 添加子网卡IP:ifconfig ens3:1 192.168.0.100/24 ...
- 找到多个与名为“HOME”的控制器匹配的类型。如果为此请求(“{CONTROLLER}/{ACTION}/{ID}”)提供服务的路由在搜索匹配此请求的控制器时没有指定命名空间,则会发生此情况。如果是这样,请通过调用含有“NAMESPACES”参数的“MAPROUTE”方法的重载来注册此路由。
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/ ...
- NGUI学习随笔
一.NGUI的直接用法 1. Attach a Collider:表示为NGUI的某些物体添加碰撞器,如果界面是用NGUI做的,只能这样添加.(注:用Component添加无效). 2. ...