Python协程整理

概念

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

优势

执行效率极高,因为子程序切换(函数)不是线程切换,由程序自身控制,没有切换线程的开销。所以与多线程相比,线程的数量越多,协程性能的优势越明显。
不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在控制共享资源时也不需要加锁,因此执行效率高很多。

说明:

协程可以处理IO密集型程序的效率问题,但是处理CPU密集型不是它的长处,如要充分发挥CPU利用率可以结合多进程+协程。

  以上只是协程的一些概念,可能听起来比较抽象,那么我结合代码讲一讲吧。这里主要介绍协程在Python的应用.Python3.4以后引入了asyncio模块,可以很好的使用协程。

Gevent

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

Install

pip install gevent

Usage

首先来看一个简单的爬虫例子:

#! -*- coding:utf-8 -*-
import gevent
from gevent import monkey;monkey.patch_all()
import urllib2
def get_body(i):
    print "start",i
    urllib2.urlopen("http://cn.bing.com")
    print "end",i
tasks=[gevent.spawn(get_body,i) for i in range(3)]
gevent.joinall(tasks)

运行结果:

start 0
start 1
start 2
end 2
end 0
end 1

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

import threading
import urllib2
def get_body(i):
    print "start",i
    urllib2.urlopen("http://cn.bing.com")
    print "end",i
for i in range(3):
    t=threading.Thread(target=get_body,args=(i,))
    t.start()

运行结果:

start 0
start 1
start 2
end 1
end 2
end 0

  说明:从结果来看,多线程与协程的效果一样,都是达到了IO阻塞时切换的功能。不同的是,多线程切换的是线程(线程间切换),协程切换的是上下文(可以理解为执行的函数)。而切换线程的开销明显是要大于切换上下文的开销,因此当线程越多,协程的效率就越比多线程的高。(猜想多进程的切换开销应该是最大的)

Gevent使用说明

monkey可以使一些阻塞的模块变得不阻塞机制:遇到IO操作则自动切换,手动切换可以用gevent.sleep(0)(将爬虫代码换成这个,效果一样可以达到切换上下文)
gevent.spawn 启动协程,参数为函数名称,参数名称
gevent.joinall 停止协程

Python3.x协程

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完成。

Usage

asyncio说明

  @asyncio.coroutine把一个generator标记为coroutine类型,然后,我们就把这个coroutine扔到EventLoop中执行。
  test()会首先打印出test_1,然后,yield from语法可以让我们方便地调用另一个generator。由于asyncio.sleep()也是一个coroutine,所以线程不会等待asyncio.sleep(),而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就可以从yield from拿到返回值(此处是None),然后接着执行下一行语句。
  把asyncio.sleep(1)看成是一个耗时1秒的IO操作,在此期间,主线程并未等待,而是去执行EventLoop中其他可以执行的coroutine了,因此可以实现并发执行。

asynico/await

  为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。
  请注意,async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

把@asyncio.coroutine替换为async;
把yield from替换为await。
Usage
例子(python3.5以后版本使用):

import asyncio
async def test(i):
    print("test_1",i)
    await asyncio.sleep(1)
    print("test_2",i)
loop=asyncio.get_event_loop()
tasks=[test(i) for i in range(5)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

运行结果与之前一致。
说明:

与前一节相比,这里只是把yield from换成了await,@asyncio.coroutine换成了async,其余不变。

gevent

协程VS多线程

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

异步爬虫

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

grequests (requests模块的异步化)
爬虫模块+gevent(比较推荐这个)
aiohttp (这个貌似资料不多,目前我也不太会用)
asyncio内置爬虫功能 (这个也比较难用)
协程池
作用:控制协程数量

from bs4 import BeautifulSoup
import requests
import gevent
from gevent import monkey, pool
monkey.patch_all()
jobs = []
links = []
p = pool.Pool(10)
urls = [
    'http://www.google.com',
    # ... another 100 urls
]
def get_links(url):
    r = requests.get(url)
    if r.status_code == 200:
        soup = BeautifulSoup(r.text)
        links + soup.find_all('a')
for url in urls:
    jobs.append(p.spawn(get_links, url))
gevent.joinall(jobs)

参考文档

https://thief.one/2017/02/20/Python%E5%8D%8F%E7%A8%8B/
https://thief.one/2018/06/21/1/

标签:

About: kiah


1,126 thoughts on “Python协程整理”

  1. I intended to create you one little note just to give thanks as before for the fantastic information you’ve discussed at this time. It has been certainly particularly generous of people like you to allow extensively all that a lot of people could possibly have distributed as an e-book to earn some cash for their own end, especially considering the fact that you could have done it if you considered necessary. The good tips also acted like a easy way to be sure that most people have a similar dreams just like mine to grasp a whole lot more in respect of this condition. I’m certain there are lots of more enjoyable moments ahead for individuals that find out your blog.

  2. I happen to be writing to make you understand what a useful experience our princess went through visiting yuor web blog. She realized too many things, with the inclusion of what it is like to possess an incredible teaching style to make the rest without problems understand various very confusing topics. You undoubtedly surpassed visitors’ expected results. Thanks for supplying those warm and friendly, trustworthy, revealing not to mention unique tips on your topic to Tanya.

  3. I needed to create you one little observation just to say thank you as before for these gorgeous knowledge you’ve discussed here. It has been certainly particularly generous of people like you to convey freely all that a lot of people could possibly have made available as an e book to earn some cash for their own end, especially considering the fact that you could possibly have done it if you ever decided. The guidelines also acted like a fantastic way to be sure that other individuals have similar dreams just like my own to grasp a whole lot more in terms of this issue. I’m sure there are many more fun occasions ahead for individuals that go through your blog post.

  4. I’m also commenting to let you be aware of of the brilliant discovery my child encountered checking the blog. She came to understand a lot of details, including how it is like to have a marvelous coaching character to get certain people completely comprehend a variety of complex issues. You actually did more than her desires. I appreciate you for coming up with such essential, dependable, edifying and cool guidance on that topic to Ethel.

  5. I simply needed to thank you so much once again. I am not sure the things that I would’ve made to happen without the type of smart ideas revealed by you over such a situation. It seemed to be a very frustrating issue in my opinion, however , observing the very specialised strategy you resolved that made me to leap over gladness. I am just happy for this information and then pray you realize what a great job you happen to be providing teaching people today thru your web page. More than likely you have never got to know any of us.

  6. I simply needed to thank you so much once again. I am not sure the things that I would’ve implemented without the type of secrets provided by you on such a question. It seemed to be a very frustrating issue in my opinion, however , observing the very specialised strategy you processed that made me to leap over gladness. I am just happy for this information and in addition pray you know what a great job you happen to be getting into teaching people thru your web page. More than likely you have never got to know any of us.

  7. I simply wished to thank you very much yet again. I do not know what I would have used without those tips and hints shown by you relating to this topic. This has been the traumatic setting in my view, nevertheless viewing your well-written way you treated the issue took me to weep with joy. Now i am thankful for your work as well as wish you recognize what an amazing job your are undertaking training the rest with the aid of your website. Probably you haven’t met any of us.

  8. My husband and i ended up being absolutely delighted Edward could complete his homework from the ideas he discovered from your very own site. It’s not at all simplistic just to continually be giving out procedures which people may have been selling. So we grasp we have got the writer to give thanks to for that. The most important illustrations you have made, the simple web site navigation, the relationships you will help foster – it’s got many incredible, and it’s really helping our son in addition to the family know that the situation is exciting, which is quite mandatory. Thank you for everything!

  9. I simply wished to thank you very much yet again. I do not know what I would have undertaken without these thoughts shared by you regarding this subject matter. It was before the scary scenario in my position, nevertheless taking note of this specialized tactic you solved the issue took me to weep with happiness. Now i’m thankful for your support and thus trust you really know what an amazing job you were putting in training the mediocre ones via your webpage. Most probably you haven’t met any of us.

  10. Dzięki za sugestii dotyczących naprawy kredytu na temat tego konkretnego sieci -teren. Rzeczy i chciałbym zaoferować jako rada ludziom oznacza zwykle zrezygnować z tej mentalności że w tym momencie i rozwidź później. Being a as be a} społeczeństwo {my|my wszyscy|my wszyscy|wielu z nas|większość z nas|większość ludzi} ma tendencję do {robienia tego|robienia tamtego|próbowania tego|zdarzyć się|powtórz to} dla wielu {rzeczy|problemów|czynników}. Obejmuje to {wakacje|wakacje|wypady|wyjazdy wakacyjne|wycieczki|rodzinne wakacje}, meble, {i|jak również|a także|wraz z|oprócz|plus} przedmiotów {chcemy|chcielibyśmy|życzymy|chcielibyśmy|naprawdę chcielibyśmy to mieć}. Jednak {musisz|musisz|powinieneś|powinieneś chcieć|wskazane jest, aby|musisz} oddzielić {swoje|swoje|to|twoje obecne|swoje|osoby} chcą {od wszystkich|z potrzeb|z}. {Kiedy jesteś|Kiedy jesteś|Kiedy jesteś|Jeśli jesteś|Tak długo, jak jesteś|Kiedy} pracujesz, aby {poprawić swój kredyt|poprawić swoją zdolność kredytową|zwiększyć swój kredyt|zwiększyć swój kredyt|podnieś swój ranking kredytowy|popraw swój kredyt} wynik {musisz zrobić|zrobić|faktycznie potrzebujesz|naprawdę musisz} dokonać kilku {poświęceń|kompromisów}. Na przykład {możesz|możesz|możesz|możesz|będziesz mógł|| możesz|prawdopodobnie możesz} robić zakupy online {aby zaoszczędzić pieniądze|aby zaoszczędzić pieniądze|aby zaoszczędzić} lub {możesz przejść do|może się zwrócić|może odwiedzić|może obejrzeć|może sprawdzić|może kliknąć} używane {sklepy|sklepy|detaliści|sprzedawcy|punkty sprzedaży|dostawcy} zamiast {drogie|drogie|drogie|drogie|drogie|drogich} domów towarowych {dla|w odniesieniu do|dotyczących|odnoszących się do|przeznaczonych dla|do zdobycia} odzieży {strzykawki insulinowe 1ml|strzykawki tuberkulinowe|strzykawki|strzykawka|strzykawki insulinowe|strzykawki do insuliny|strzykawki trzyczęściowe tuberkulinowe|strzykawka tuberkulinowa|strzykawka insulinowa|strzykawka do insuliny|strzykawka trzyczęściowe tuberkulinowa} {strzykawki insulinowe 1ml|strzykawki tuberkulinowe|strzykawki|strzykawka|strzykawki insulinowe|strzykawki do insuliny|strzykawki trzyczęściowe tuberkulinowe|strzykawka tuberkulinowa|strzykawka insulinowa|strzykawka do insuliny|strzykawka trzyczęściowe tuberkulinowa}.

  11. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  12. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  13. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  14. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  15. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  16. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  17. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  18. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  19. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  20. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  21. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  22. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  23. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  24. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  25. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  26. Холостячка 2 сезон https://bit.ly/39ioLkW Смотреть онлайн шоу Холостячка 2 сезон на СТБ.
    Пост шоу можно смотреть тут. Холостячка стб 2 сезон 1-2 серия

  27. Бій Ентоні Джошуа проти Олександра Усика (англ. Anthony Joshua vs. Oleksandr Usyk) — майбутній професійний боксерський поєдинок, який відбудеться між чемпіонами WBA (Супер), IBF, WBO та IBO у важкій вазі Ентоні Джошуа та колишнім Смотреть онлайн прямую трансляцию боя Энтони Джошуа – Александр Усик 25.09.2021 Бокс Видео бокса Шанс Усика в поєдинку з Джошуа – провести найкращий бій у

  28. Энтони Джошуа и Александр Усик Известный американский тренер Мэнни Роблес высказался о предстоящем поединке между обладателем поясов WBA, WBO и IBF в супертяжелом дивизионе Энтони Джошуа и Энтони Джошуа Александр Усик смотреть онлайн Кантарът преди Джошуа срещу Усик: Близо 10 кг в полза на

  29. Усик – Джошуа: смотреть онлайн-трансляцию боя 25.09.2021. Украинский супертяжеловес Александр Усик (18-0, 13 КО) проведет поединок против британского чемпиона wba, wbo и ibf Энтони Джошуа (24-1, 22 КО). Александр Усик Энтони Джошуа смотреть онлайн Усик Джошуа – британець може

  30. Снимка на деня: Джошуа и Усик очи в очи преди мача за Усик Джошуа смотреть онлайн 07:40. Болельщики считают, что Усик побьёт Джошуа. Комментирует Эдди Хирн. 25.08.21. 19:10. Энтони Джошуа сравнил себя с Месси и рассказал о подготовке к Усику. 24.08.21. 13:05. Энтони Джошуа назвал ключ к

  31. Поединок Усик – Джошуа пройдет 25 сентября в Лондоне. Бедное детство, футбол, ОИ-2012, Али, лагерь Кличко. У Джошуа и Усика много общего Александр Усик Энтони Джошуа смотреть онлайн Усик оказался легче Джошуа на 8 кг – Читайте подробнее на сайте РТ на Все подробности на сайте imag.one