Python自动化之select、greenlet和gevent和事件驱动模型初探
进程、线程和协程的区别
进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。
协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。
Greenlet模块
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from greenlet import greenlet
def test1():
    print 12
    gr2.switch()
    print 34
    gr2.switch()
def test2():
    print 56
    gr1.switch()
    print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
每一个greenlet其实就是一个函数,以及保存这个函数执行时的上下文.对于函数来说上下文也就是其stack。
greenlet需要你自己来处理线程切换, 就是说,你需要自己指定现在执行哪个greenlet再执行哪个greenlet。
Gevent(第三方库)
import gevent
def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')
def bar():
    print('Explicit context to bar')
    gevent.sleep(0)
    print('Implicit context switch back to bar')
gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
])
gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。
gevent.sleep()来互相切换,实际上gevent是可以自动切换的。
遇到IO自动切换任务
from gevent import monkey; monkey.patch_all()
import gevent
from  urllib.request import urlopen
def f(url):
    print('GET: %s' % url)
    resp = urlopen(url)
    data = resp.read()
    print('%d bytes received from %s.' % (len(data), url))
gevent.joinall([
        gevent.spawn(f, 'https://www.python.org/'),
        gevent.spawn(f, 'https://www.yahoo.com/'),
        gevent.spawn(f, 'https://github.com/'),
])
通过gevent实现单线程下的多socket并发
服务端
import sys
import socket
import time
import gevent
from gevent import socket,monkey
monkey.patch_all()
def server(port):
    s = socket.socket()
    s.bind(('0.0.0.0', port))
    s.listen(500)
    while True:
        cli, addr = s.accept()
        gevent.spawn(handle_request, cli)
def handle_request(conn):
    try:
        while True:
            data = conn.recv(1024)
            print("recv:", data)
            conn.send(data)
            if not data:
                conn.shutdown(socket.SHUT_WR)
    except Exception as  ex:
        print(ex)
    finally:
        conn.close()
if __name__ == '__main__':
    server(8001)
客户端
import socket
HOST = 'localhost'    # The remote host
PORT = 8001           # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
    msg = bytes(input(">>:"),encoding="utf8")
    s.sendall(msg)
    data = s.recv(1024)
    #print(data)
    print('Received', repr(data))
s.close()
事件驱动模型
目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
- 有一个事件(消息)队列;
- 鼠标按下时,往这个队列中增加一个点击事件(消息);
- 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
- 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;
  
Python自动化之select、greenlet和gevent和事件驱动模型初探的更多相关文章
- Python的requests、greenlet和gevent模块在windows下安装
		一.requests模块在windows下安装 Linux系统下requests的安装方法在http://docs.python-requests.org/en/latest/user/install ... 
- Python自动化开发 - select模块
		介绍: IO-多路复用:监听多个socker对象是否有变化,包括可读.可写.发送错误 Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个 ... 
- Python自动化之select解析
		select原理 网络通信被Unix系统抽象为文件的读写,通常是一个设备,由设备驱动程序提供,驱动可以知道自身的数据是否可用.支持阻塞操作的设备驱动通常会实现一组自身的等待队列,如读/写等待队列用于支 ... 
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
		一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ... 
- Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO
		本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO 1. 多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ... 
- {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二
		python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ... 
- python中的协程:greenlet和gevent
		python中的协程:greenlet和gevent 协程是一中多任务实现方式,它不需要多个进程或线程就可以实现多任务. 1.通过yield实现协程: 代码: import time def A(): ... 
- Python自动化运维之15、网络编程之socket、socketserver、select、twisted
		一.TCP/IP相关知识 TCP/UDP提供进程地址,两个协议互不干扰的独自的协议 TCP :Transmission Control Protocol 传输控制协议,面向连接的协议,通信 ... 
- 【python自动化第十一篇】
		[python自动化第十一篇:] 课程简介 gevent协程 select/poll/epoll/异步IO/事件驱动 RabbitMQ队列 上节课回顾 进程: 进程的诞生时为了处理多任务,资源的隔离, ... 
随机推荐
- Java——文件选择框:JFileChooser
			import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import j ... 
- Java适配器设计模式
			适配器设计模式,一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(但是这个抽象类中的方法体是空的),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法. ... 
- JavaScript学习笔记——DOM_document对象
			javascript-document对象详解 DOM document(html xml) object modledocument对象(DOM核心对象) 作用: 1.内容 innerHTML 2. ... 
- perspective属性
			1. 目前只有safari和chrome浏览器支持 -webkit-perspective. 2. 单位为像素 { -webkit-perspective:500 } 该属性只影响子元素的的透视效果. 
- C语言进行面向对象编程
			http://blog.csdn.net/dadalan/article/details/3983888 http://blog.163.com/zhqh43@126/blog/static/4043 ... 
- android 点击屏幕关闭 软键盘
			//点击屏幕 关闭输入弹出框 @Override public boolean onTouchEvent(MotionEvent event) { InputMethodManager im = (I ... 
- Java常见的几种内存溢出及解决方法
			Java常见的几种内存溢出及解决方法[情况一]:java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一 ... 
- JavaWeb学习总结(一)——JavaWeb开发入门
			http://www.cnblogs.com/xdp-gacl/p/3729033.html 只为成功找方法,不为失败找借口! JavaWeb学习总结(一)--JavaWeb开发入门 一.基本概念 1 ... 
- ps切图设置
			1. 新建设置 文件->新建->预设->自定义 1920 像素 2000 像素 72 像素/英寸 背景内容 透明 存储预设 2.视图设置 视图->显示->智能参考线选中视 ... 
- [c#]获取exchange中的图片
			摘要 在exchange 2007或者2010中获取的邮件内容为html标签格式,也就是一个页面.如果里面含有img标签,你会发现img标签的src属性为cid:xxxxxxxxxxxx的一串字符串, ... 
