最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單了解python gevent 協(xié)程使用及作用

 更新時間:2019年07月22日 11:05:40   作者:jihite  
這篇文章主要介紹了簡單了解python gevent 協(xié)程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

簡介

沒有切換開銷。因為子程序切換不是線程切換,而是由程序自身控制,沒有線程切換的開銷,因此執(zhí)行效率高,

不需要鎖機制。因為只有一個線程,也不存在同時寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比多線程高很多

Python對協(xié)程的支持還非常有限,用在generator中的yield可以一定程度上實現(xiàn)協(xié)程。

yield

傳統(tǒng)的生產(chǎn)者-消費者模型是一個線程寫消息,一個線程取消息,通過鎖機制控制隊列和等待,但一不小心就可能死鎖。

如果改用協(xié)程,生產(chǎn)者生產(chǎn)消息后,直接通過yield跳轉(zhuǎn)到消費者開始執(zhí)行,待消費者執(zhí)行完畢后,切換回生產(chǎn)者繼續(xù)生產(chǎn),效率極高

代碼

import time

def consumer():
  r = ''
  while True:
    n = yield r
    if not n:
      return
    print('[CONSUMER] Consuming %s....' % n)
    r = '200 OK'

def produce(c):
  c.next()
  n = 0
  while n < 5:
    n = n + 1
    print('[PRODUCER] Producing %s...' % n)
    r = c.send(n)
    print('[PRODUCER] Consumer return: %s\n' % r)
  c.close()

if __name__=='__main__':
  c = consumer()
  produce(c)

結(jié)果

[PRODUCER] Producing 1...
[CONSUMER] Consuming 1....
[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 2...
[CONSUMER] Consuming 2....
[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 3...
[CONSUMER] Consuming 3....
[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 4...
[CONSUMER] Consuming 4....
[PRODUCER] Consumer return: 200 OK

[PRODUCER] Producing 5...
[CONSUMER] Consuming 5....
[PRODUCER] Consumer return: 200 OK

分析

  • 首先調(diào)用c.next()啟動生成器
  • 然后,一旦生產(chǎn)了東西,通過c.send(n)切換到consumer執(zhí)行
  • consumer通過yield拿到消息,處理,又通過yield把結(jié)果傳回
  • produce拿到consumer處理的結(jié)果,繼續(xù)生產(chǎn)下一條消息

整個過程無鎖,由一個線程執(zhí)行,producer和consumer寫作完成任務,所以叫做協(xié)程

gevent

Python通過yield提供了對協(xié)程的基本支持,但是不完全。而第三方的gevent為Python提供了比較完善的協(xié)程支持

gevent是第三方庫,通過greenlet實現(xiàn)協(xié)程,其基本思想是:

當一個greenlet遇到IO操作時(比如訪問網(wǎng)絡),就自動切換到其他的greenlet,等到IO操作完成,再在適當?shù)臅r候切換回來繼續(xù)執(zhí)行。由于IO操作非常耗時,經(jīng)常使程序處于等待狀態(tài),有了gevent為我們自動切換協(xié)程,就保證總有g(shù)reenlet在運行,而不是等待IO。

import gevent

def f(n):
  for i in range(n):
    print gevent.getcurrent(), i

g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)

g1.join()
g2.join()
g3.join()

結(jié)果

<Greenlet at 0x7f7216efbe10: f(5)> 0
<Greenlet at 0x7f7216efbe10: f(5)> 1
<Greenlet at 0x7f7216efbe10: f(5)> 2
<Greenlet at 0x7f7216efbe10: f(5)> 3
<Greenlet at 0x7f7216efbe10: f(5)> 4
<Greenlet at 0x7f720f54e0f0: f(5)> 0
<Greenlet at 0x7f720f54e0f0: f(5)> 1
<Greenlet at 0x7f720f54e0f0: f(5)> 2
<Greenlet at 0x7f720f54e0f0: f(5)> 3
<Greenlet at 0x7f720f54e0f0: f(5)> 4
<Greenlet at 0x7f720f54e190: f(5)> 0
<Greenlet at 0x7f720f54e190: f(5)> 1
<Greenlet at 0x7f720f54e190: f(5)> 2
<Greenlet at 0x7f720f54e190: f(5)> 3
<Greenlet at 0x7f720f54e190: f(5)> 4

可以看出3個greenlet依次運行,而不是交替運行

要讓greenlet交替運行,可以通過gevent.sleep()交出控制權(quán)

import gevent

def f(n):
  for i in range(n):
    print gevent.getcurrent(), i
    gevent.sleep(1)

g1 = gevent.spawn(f, 3)
g2 = gevent.spawn(f, 3)
g3 = gevent.spawn(f, 3)

g1.join()
g2.join()
g3.join()

結(jié)果

<Greenlet at 0x7f74e2179e10: f(3)> 0
<Greenlet at 0x7f74da7cb0f0: f(3)> 0
<Greenlet at 0x7f74da7cb190: f(3)> 0
<Greenlet at 0x7f74e2179e10: f(3)> 1
<Greenlet at 0x7f74da7cb0f0: f(3)> 1
<Greenlet at 0x7f74da7cb190: f(3)> 1
<Greenlet at 0x7f74e2179e10: f(3)> 2
<Greenlet at 0x7f74da7cb0f0: f(3)> 2
<Greenlet at 0x7f74da7cb190: f(3)> 2

可以看出3個greenlet是交替執(zhí)行

如果把循環(huán)改為1000,讓執(zhí)行次數(shù)執(zhí)行時間長些,查看進程,可以看到線程只有一個。

當然,實際代碼中,不可能用gevent.sleep()去切換協(xié)程,而是在執(zhí)行IO操作是,gevent自動切換,參考代碼如下

import gevent
from gevent import monkey; monkey.patch_all()
import urllib2

def f(url):
  print 'GET: %s' % url
  resp = urllib2.urlopen(url)
  data = resp.read()
  print '[%d] bytes received from %s\n' %(len(data), url)

gevent.joinall([
gevent.spawn(f, 'http://www.cnblogs.com/kaituorensheng/'),
gevent.spawn(f, 'https://www.python.org/'),
gevent.spawn(f, 'https://www.baidu.com'),
])

執(zhí)行結(jié)果

GET: http://www.cnblogs.com/kaituorensheng/
GET: https://www.python.org/
GET: https://www.baidu.com
[227] bytes received from https://www.baidu.com

[14667] bytes received from http://www.cnblogs.com/kaituorensheng/

[47348] bytes received from https://www.python.org/

可以看到3個url結(jié)束順序并不是依次執(zhí)行完的。


使用gevent,可以獲得極高的并發(fā)性能,但gevent只能在Unix/Linux下運行,在Windows下不保證正常安裝和運行。

由于gevent是基于IO切換的協(xié)程,所以最神奇的是,我們編寫的Web App代碼,不需要引入gevent的包,也不需要改任何代碼,僅僅在部署的時候,用一個支持gevent的WSGI服務器,立刻就獲得了數(shù)倍的性能提升。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python處理中文標點符號大集合

    Python處理中文標點符號大集合

    中文文本中可能出現(xiàn)的標點符號來源比較復雜,通過匹配等手段對他們處理的時候需要格外小心,防止遺漏,下面小編給大家?guī)砹薖ython處理中文標點符號大集合,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-05-05
  • Python unittest 自動識別并執(zhí)行測試用例方式

    Python unittest 自動識別并執(zhí)行測試用例方式

    這篇文章主要介紹了Python unittest 自動識別并執(zhí)行測試用例方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python元組的概念知識點

    python元組的概念知識點

    在本篇文章里我們給各位整理的是關(guān)于python元組的概念知識點以及實例內(nèi)容,需要的朋友們參考下。
    2019-11-11
  • django項目中使用云片網(wǎng)發(fā)送短信驗證碼的實現(xiàn)

    django項目中使用云片網(wǎng)發(fā)送短信驗證碼的實現(xiàn)

    這篇文章主要介紹了django項目中使用云片網(wǎng)發(fā)送短信驗證碼的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • 如何使用Python快速生成gif圖

    如何使用Python快速生成gif圖

    這篇文章主要給大家介紹了關(guān)于如何使用Python快速生成gif圖的相關(guān)資料,我們需要用到 imageio 庫,文章通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • pycharm通過ssh遠程連接服務器并運行代碼詳細圖文

    pycharm通過ssh遠程連接服務器并運行代碼詳細圖文

    在運行項目的過程中,由于自己電腦GPU不夠,通常需要將項目放到服務器上運行,這時就會遇到如何將pycharm和服務器進行連接,下面這篇文章主要給大家介紹了關(guān)于pycharm通過ssh遠程連接服務器并運行代碼的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • pytorch實現(xiàn)onehot編碼轉(zhuǎn)為普通label標簽

    pytorch實現(xiàn)onehot編碼轉(zhuǎn)為普通label標簽

    今天小編就為大家分享一篇pytorch實現(xiàn)onehot編碼轉(zhuǎn)為普通label標簽,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • pandas DataFrame.shift()函數(shù)的具體使用

    pandas DataFrame.shift()函數(shù)的具體使用

    本文主要介紹了pandas DataFrame.shift()函數(shù)的使用,pandas DataFrame.shift()函數(shù)可以把數(shù)據(jù)移動指定的位數(shù),有需要了解pandas DataFrame.shift()用法的朋友可以參考一下
    2021-05-05
  • 淺談python 中類屬性共享的問題

    淺談python 中類屬性共享的問題

    今天小編就為大家分享一篇淺談python 中類屬性共享的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python中find()的用法小結(jié)

    Python中find()的用法小結(jié)

    Python中find()函數(shù)用于在字符串中查找目標字符或子字符串,并返回索引,本文就來介紹一下Python中find()的用法,具有一定的參考價值,感興趣的可以了解一下
    2024-12-12

最新評論

连州市| 石首市| 平陆县| 卢氏县| 咸宁市| 达尔| 库尔勒市| 定兴县| 许昌县| 濉溪县| 锡林浩特市| 禄劝| 嘉兴市| 漯河市| 沙坪坝区| 汪清县| 郓城县| 淮滨县| 习水县| 大洼县| 大关县| 龙江县| 潞西市| 浦东新区| 西充县| 清流县| 绍兴市| 余姚市| 丹东市| 从化市| 丽水市| 含山县| 景宁| 中方县| 桐城市| 北辰区| 双江| 慈利县| 化德县| 广丰县| 玉环县|