日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python协程(真才实学,想学的进来)

發布時間:2024/2/28 python 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python协程(真才实学,想学的进来) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

真正有知識的人的成長過程,就像麥穗的成長過程:麥穗空的時候,麥子長得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時,它們開始謙虛,垂下麥芒。
——蒙田《蒙田隨筆全集》


在這里還是要推薦下我自己建的Python開發學習群:725479218,群里都是學Python開發的,如果你正在學習Python ,小編歡迎你加入,大家都是軟件開發黨,不定期分享干貨(只有Python軟件開發相關的),包括我自己整理的一份2018最新的Python進階資料和高級開發教程,歡迎進階中和進想深入Python的小伙伴
上篇論述了關于python多線程是否是雞肋的問題,得到了一些網友的認可,當然也有一些不同意見,表示協程比多線程不知強多少,在協程面前多線程算是雞肋。好吧,對此我也表示贊同,然而上篇我論述的觀點不在于多線程與協程的比較,而是在于IO密集型程序中,多線程尚有用武之地。

對于協程,我表示其效率確非多線程能比,但本人對此了解并不深入,因此最近幾日參考了一些資料,學習整理了一番,在此分享出來僅供大家參考,如有謬誤請指正,多謝。

申明:本文介紹的協程是入門級別,大神請繞道而行,謹防入坑。

文章思路:本文將先介紹協程的概念,然后分別介紹Python2.x與3.x下協程的用法,最終將協程與多線程做比較并介紹異步爬蟲模塊。

協程

概念

協程,又稱微線程,纖程,英文名Coroutine。協程的作用,是在執行函數A時,可以隨時中斷,去執行函數B,然后中斷繼續執行函數A(可以自由切換)。但這一過程并不是函數調用(沒有調用語句),這一整個過程看似像多線程,然而協程只有一個線程執行。

優勢

  • 執行效率極高,因為子程序切換(函數)不是線程切換,由程序自身控制,沒有切換線程的開銷。所以與多線程相比,線程的數量越多,協程性能的優勢越明顯。
  • 不需要多線程的鎖機制,因為只有一個線程,也不存在同時寫變量沖突,在控制共享資源時也不需要加鎖,因此執行效率高很多。

  說明:協程可以處理IO密集型程序的效率問題,但是處理CPU密集型不是它的長處,如要充分發揮CPU利用率可以結合多進程+協程。

以上只是協程的一些概念,可能聽起來比較抽象,那么我結合代碼講一講吧。這里主要介紹協程在Python的應用,Python2對協程的支持比較有限,生成器的yield實現了一部分但不完全,gevent模塊倒是有比較好的實現;Python3.4以后引入了asyncio模塊,可以很好的使用協程。

Python2.x協程

python2.x協程應用:

  • yield
  • gevent

python2.x中支持協程的模塊不多,gevent算是比較常用的,這里就簡單介紹一下gevent的用法。

Gevent

gevent是第三方庫,通過greenlet實現協程,其基本思想:
  當一個greenlet遇到IO操作時,比如訪問網絡,就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。由于IO操作非常耗時,經常使程序處于等待狀態,有了gevent為我們自動切換協程,就保證總有greenlet在運行,而不是等待IO。

Install

pip install gevent
最新版貌似支持windows了,之前測試好像windows上運行不了……

Usage

首先來看一個簡單的爬蟲例子:

?

#! -*- coding:utf-8 -*- import gevent from gevent import monkey;monkey.patch_all() import urllib2 def get_body(i):print "start",iurllib2.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",iurllib2.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.5協程使用可以移步:Python3.5協程學習研究

為了測試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完成。

Usage

例子:(需在python3.4以后版本使用)

?

import asyncio @asyncio.coroutine def test(i):print("test_1",i)r=yield from 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()

運行結果:

?

test_1 3 test_1 4 test_1 0 test_1 1 test_1 2 test_2 3 test_2 0 test_2 2 test_2 4 test_2 1

說明:從運行結果可以看到,跟gevent達到的效果一樣,也是在遇到IO操作時進行切換(所以先輸出test_1,等test_1輸出完再輸出test_2)。但此處我有一點不明,test_1的輸出為什么不是按照順序執行的呢?可以對比gevent的輸出結果(希望大神能解答一下)。

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

同python2.x用法一樣。

協程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)



作者:IT未來家
鏈接:https://www.jianshu.com/p/46cfc324c354
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

總結

以上是生活随笔為你收集整理的Python协程(真才实学,想学的进来)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人手机在线视频 | 日韩sese | 波多野结衣99 | 国产无遮挡免费 | 都市激情一区 | 国产一区二区三区中文字幕 | 激情婷婷网| 97午夜| 黄色录像a级片 | 亚洲视频在线看 | 国产夫妻自拍小视频 | 黄色天堂| 韩国黄色av | 无人在线观看的免费高清视频 | 欧美精品免费看 | 中文字幕在线视频一区二区三区 | av大帝在线观看 | 亚洲女人在线 | 国产成人亚洲综合a∨婷婷 台湾a级片 | 亚洲热视频 | 欧美影院一区二区三区 | 国产人妻黑人一区二区三区 | 亚洲黄色免费电影 | 男女无遮挡做爰猛烈视频 | 欧美性猛交 | 夜色在线影院 | 蜜桃视频在线观看一区二区 | 蜜臀视频一区二区三区 | 国产二级一片内射视频播放 | 粉色午夜视频 | 国产猛男猛女超爽免费视频 | 天天色宗合 | 黄色短视频在线观看 | www.99精品| 丝袜 中出 制服 人妻 美腿 | 精品一区二区在线观看视频 | 久久综合99| av在线播放国产 | 国产主播自拍av | 色婷婷激情五月 | 蜜桃久久久| 亚洲精品电影在线 | 久色视频在线播放 | ,亚洲人成毛片在线播放 | 国产精品制服诱惑 | 牛夜精品久久久久久久99黑人 | 国产日韩欧美精品一区 | 四虎永久网址 | 韩国三级视频在线 | 狠狠躁夜夜躁人人爽天天高潮 | 操日本老妇 | 爽好多水快深点欧美视频 | 天天爱天天爽 | 亚洲成人av电影 | 中文字幕福利视频 | 国产成人精品一区 | 爱豆国产剧免费观看大全剧集 | 久久中出 | 人禽l交视频在线播放 视频 | 国产一区二区视频在线播放 | 欧美老女人视频 | 先锋av网| 国产成人宗合 | 亚洲黄色大片 | 欧美乱做爰xxxⅹ久久久 | 日本欧美国产 | 久久中字 | 一级黄色片毛片 | 4438x亚洲最大 | 国产精品国产三级国产专播品爱网 | 99久久一区二区 | 中文字幕免费视频观看 | 免费在线观看黄色 | 激情xxx| 一本色道久久加勒比精品 | 风韵少妇性饥渴推油按摩视频 | 日本在线天堂 | 亚洲黄色在线免费观看 | 99riav国产| 免费在线观看www | 亚洲精品高清视频在线观看 | 奇米第四色在线 | 全部免费毛片在线播放 | 亚洲精品在线观看av | 男人久久久 | 欲求不满的岳中文字幕 | 日韩人成 | 日皮在线观看 | 日韩精品极品视频在线观看免费 | 一区二区国产电影 | 夜夜操影视 | 国产精品福利一区 | 欧美18av | 特高潮videossexhd | 亚洲一区二区免费电影 | 蜜桃在线一区二区三区 | 日韩美女视频在线 | 黄色视屏免费 | 最近高清中文在线字幕在线观看 |