美文网首页Python新世界机器学习与数据挖掘机器学习
谁说Python协程是鸡肋的!站出来我不打死他!这么牛逼的协程!

谁说Python协程是鸡肋的!站出来我不打死他!这么牛逼的协程!

作者: 919b0c54458f | 来源:发表于2018-08-09 11:03 被阅读6次

    文章思路:本文将先介绍协程的概念,然后分别介绍Python2.x与3.x下协程的用法,最终将协程与多线程做比较并介绍异步爬虫模块。

    协程

    概念

    协程,又称微线程,纤程,英文名Coroutine。协程的作用,是在执行函数A时,可以随时中断,去执行函数B,然后中断继续执行函数A(可以自由切换)。但这一过程并不是函数调用(没有调用语句),这一整个过程看似像多线程,然而协程只有一个线程执行。

    进群:548377875  即可获取数十套PDF哦!

    Python2.x协程

    python2.x协程应用:

    yield

    gevent

    python2.x中支持协程的模块不多,gevent算是比较常用的,这里就简单介绍一下gevent的用法。

    Gevent

    gevent是第三方库,通过greenlet实现协程,其基本思想:

    当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

    运行结果:

    start 0

    start 1

    start 2

    end 2

    end 0

    end 1

    说明:从结果上来看,执行get_body的顺序应该先是输出”start”,然后执行到urllib2时碰到IO堵塞,则会自动切换运行下一个程序(继续执行get_body输出start),直到urllib2返回结果,再执行end。也就是说,程序没有等待urllib2请求网站返回结果,而是直接先跳过了,等待执行完毕再回来获取返回值。值得一提的是,在此过程中,只有一个线程在执行,因此这与多线程的概念是不一样的。

    Gevent使用说明

    monkey可以使一些阻塞的模块变得不阻塞,机制:遇到IO操作则自动切换,手动切换可以用gevent.sleep(0)(将爬虫代码换成这个,效果一样可以达到切换上下文)

    gevent.spawn 启动协程,参数为函数名称,参数名称

    gevent.joinall 停止协程

    Python3.x协程

    为了测试Python3.x下的协程应用,我在virtualenv下安装了python3.6的环境。

    python3.x协程应用:

    asynico + yield from(python3.4)

    asynico + await(python3.5)

    gevent

    Python3.4以后引入了asyncio模块,可以很好的支持协程。

    asynico

    asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。asyncio的异步操作,需要在coroutine中通过yield from完成。

    说明:从运行结果可以看到,跟gevent达到的效果一样,也是在遇到IO操作时进行切换(所以先输出test_1,等test_1输出完再输出test_2)。但此处我有一点不明,test_1的输出为什么不是按照顺序执行的呢?可以对比gevent的输出结果(希望大神能解答一下)。

    Usage

    例子(python3.5以后版本使用):

    gevent

    同python2.x用法一样。

    协程VS多线程

    如果通过以上介绍,你已经明白多线程与协程的不同之处,那么我想测试也就没有必要了。因为当线程越来越多时,多线程主要的开销花费在线程切换上,而协程是在一个线程内切换的,因此开销小很多,这也许就是两者性能的根本差异之处吧。(个人观点)

    异步爬虫

    也许关心协程的朋友,大部分是用其写爬虫(因为协程能很好的解决IO阻塞问题),然而我发现常用的urllib、requests无法与asyncio结合使用,可能是因为爬虫模块本身是同步的(也可能是我没找到用法)。那么对于异步爬虫的需求,又该怎么使用协程呢?或者说怎么编写异步爬虫?

    grequests (requests模块的异步化)

    爬虫模块+gevent(比较推荐这个)

    aiohttp (这个貌似资料不多,目前我也不太会用)

    asyncio内置爬虫功能 (这个也比较难用)

    协程池

    作用:控制协程数量

    get去吧!

    相关文章

      网友评论

        本文标题:谁说Python协程是鸡肋的!站出来我不打死他!这么牛逼的协程!

        本文链接:https://www.haomeiwen.com/subject/hzsqbftx.html