Python协程

1. 协程是啥

线程和进程的操作是由程序触发系统接口,最后的执行者是系统,它本质上是操作系统提供的功能。而协程的实质是程序员指定的,在python中遇到yield阻塞,则调用另一代码块执行,人为的实现并发处理,可以理解为根据现有的机制虚拟出的概念。

协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时。协程,则只使用一个线程,分解一个线程成为多个“微线程”,在一个线程中规定某个代码块的执行顺序。

2. 计算密集型和IO密集型

计算密集型 ---> 例如for循环里嵌套10层for循环  --> 占大量的cpu资源 -->  解决方案 --> 使用多进程不能用多线程 (多线程中有个全局锁GIL)

IO密集型 ---> 需要网络功能,大量的事件等待网络数据的到来(例如爬虫) -->多线程、协程

3. 协程的好处

把一个IO操作 写成一个协程。当触发IO操作的时候就自动让出CPU给其他协程。要知道协程的切换很轻的。 协程通过这种对异步IO的封装 既保留了性能也保证了代码的容易编写和可读性。在高IO密集型的程序下很好。但是高CPU密集型的程序下没啥好处。

4、协程-gevent-自动切换

在python3中安装greenlet

sudo pip3 install python3-pip

sudo pip3 install gevent

gevent里面把socket重新封装了,用的时候就用gevent里面的monkey patch指的是在运行时动态替换,一般是在startup的时候,

用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all(); 

把标准库中的thread/socket等给替换掉.这样我们在后面使用socket的时候可以跟平常一样使用,无需修改任何代码,但是它变成非阻塞的了.

import sys
import time
import gevent
from gevent import socket,monkey
monkey.patch_all()
def handle_request(conn):
    while True:
        data = conn.recv(1024)
        if not data:
            conn.close()
            break
        print("recv:", data)
        conn.send(data)

def server(port):
    s = socket.socket()
    s.bind(('', port))
    s.listen(5)
    while True:
        newSocket, addr = s.accept()
        gevent.spawn(handle_request, newSocket)
if __name__ == '__main__':
    server(7777)

5. tornado框架

tornado中的协程实现基于python语言的Generator并且结合一个全局的调度器IOLoop,Generator通过函数装饰器coroutine和IOLoop进行通信。IOLoop并没有直接控制能力,调度恢复被暂停的协程继续执行。future对象在协程中被yield。协程暂停,IOLoop调度另外一个代码模块执行,也就是callback函数,而在callback中,刚好可以访问到属于被暂停协程中的future对象,将其set_result,给IOLoop发送信号,间接恢复暂停的协程执行。不同执行代码模块中,共享future对象。

对于tornado,传说的异步并发框架,实质就是协程实现的比较完善。具体代码抽空分析,如果深入研究并发原理,还必须把tornado框架研究明白。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值