欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

簡單了解python gevent 協程使用及作用

系統 2191 0

簡介

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

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

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

yield

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

如果改用協程,生產者生產消息后,直接通過yield跳轉到消費者開始執行,待消費者執行完畢后,切換回生產者繼續生產,效率極高

代碼

            
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)
          

結果

            
[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
          

分析

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

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

gevent

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

gevent是第三方庫,通過greenlet實現協程,其基本思想是:

當一個greenlet遇到IO操作時(比如訪問網絡),就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。由于IO操作非常耗時,經常使程序處于等待狀態,有了gevent為我們自動切換協程,就保證總有greenlet在運行,而不是等待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()
          

結果

            
               0

              
                 1

                
                   2

                  
                     3

                    
                       4

                      
                         0

                        
                           1

                          
                             2

                            
                               3

                              
                                 4

                                
                                   0

                                  
                                     1

                                    
                                       2

                                      
                                         3

                                        
                                           4
                                        
                                      
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            
          

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

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

            
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()
          

結果

            
               0

              
                 0

                
                   0

                  
                     1

                    
                       1

                      
                         1

                        
                           2

                          
                             2

                            
                               2
                            
                          
                        
                      
                    
                  
                
              
            
          

可以看出3個greenlet是交替執行

如果把循環改為1000,讓執行次數執行時間長些,查看進程,可以看到線程只有一個。

當然,實際代碼中,不可能用gevent.sleep()去切換協程,而是在執行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'),
])
          

執行結果

            
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結束順序并不是依次執行完的。


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

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

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美又黄又嫩大片a级 | 成年人看的羞羞网站 | 国产午夜亚洲精品一区 | 青娱分类视频精品免费2 | 欧美成人二区 | 日韩欧美国产一区二区 | 久久一日本道色综合久久 | 99久久一区二区 | 欧美久久综合 | xxx欧美老熟| 亚州AV无码乱码色情 | 久久久999| 亚洲精品麻豆 | 日韩中文一区二区三区 | 九九色综合| 人人看人人干 | 成人欧美一区在线视频在线观看 | 日韩高清不卡 | 国产精品免费大片一区二区 | a免费国产一级特黄aa大 | 日韩高清中文字幕 | 国产男女自拍视频 | 国产精品亚洲综合第一区 | 欧美日韩国产一区二区三区 | 欧美三级视频在线观看 | 国产成人91高清精品免费 | 久久黄视频| 国产日韩一区在线精品欧美玲 | 欧美一区二区三区精品国产 | 一级毛片免费在线播放 | 久久久婷婷一区二区三区不卡 | 日本成人在线网站 | 午夜成人免费视频 | 操人视频 | 免费看一区二区三区 | 日韩精品免费视频 | 久久久久久久99精品免费观看 | 成人性生交A片免费网 | 国产一区二区三区久久久久久久久 | 亚洲视频在线观看 | 欧美一级网站 |