簡體   English   中英

使用Bottlepy-Gevent生成多個Greenlet

[英]Spawning multiple greenlets using Bottlepy-Gevent

我是異步編程的新手,並且這里還介紹了Bottlepy-gevent教程。

我運行了頁面上給出的程序:

from gevent import monkey; monkey.patch_all()

from time import sleep
from bottle import route, run

@route('/stream')
def stream():
    yield 'START'
    sleep(3)
    yield 'MIDDLE'
    sleep(5)
    yield 'END'

run(host='0.0.0.0', port=8080, server='gevent')

當我訪問URL http://localhost:8080/stream時,它按預期方式工作,分別在3秒和5秒的睡眠間隔內打印STARTMIDDLEEND

根據文檔,

猴子修補使gevent能夠阻止Python的阻塞API(以及諸如time.sleep()之類的函數)阻塞當前線程,並將CPU傳遞給下一個greenlet。

但是,當我修改上面的代碼以打印當前的greenlet信息時,我將相同的greenlet實例用於所有三個yield語句。

import gevent
from gevent import monkey
monkey.patch_all()

from time import sleep
from bottle import route, run

@route('/stream')
def stream():
    print(gevent.getcurrent())
    yield 'START '
    sleep(3)
    print(gevent.getcurrent())
    yield 'MIDDLE '
    sleep(5)
    print(gevent.getcurrent())
    yield 'END'

run(host='0.0.0.0', port=8080, server='gevent')

控制台輸出:

<Greenlet at 0x7f9fd733a9c8: _handle_and_close_when_done(<bound method WSGIServer.handle of <WSGIServer at , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket object, fd=7, family=2, t)>
<Greenlet at 0x7f9fd733a9c8: _handle_and_close_when_done(<bound method WSGIServer.handle of <WSGIServer at , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket object, fd=7, family=2, t)>
<Greenlet at 0x7f9fd733a9c8: _handle_and_close_when_done(<bound method WSGIServer.handle of <WSGIServer at , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket object, fd=7, family=2, t)>

根據瓶裝文檔,是否不應該在每次執行time.sleep()時生成一個新的greenlet實例?

而且,當我運行類似的程序而不使用gevent和Monkey-patching時,如下所示:

from time import sleep
from bottle import route, run

@route('/stream')
def stream():
    yield 'START \n'
    sleep(3)
    yield 'MIDDLE \n'
    sleep(5)
    yield 'END'

run(host='0.0.0.0', port=8080)

我得到與以前相同的響應(START之后是MIDDLE,然后在3和5秒處結束),這與Bottlepy文檔的注釋相反,以下為黑體字:

如果運行此腳本並將瀏覽器指向http:// localhost:8080 / stream ,則應該看到START,MIDDLE和END逐一顯示( 而不是等待8秒才能一次看到它們 )。

我在這里想念什么嗎?

2個答案:

  • 來自服務器的每個請求都將產生一個新的greenlet ,因此在同一請求中,您將看到相同的暫停和恢復。 嘗試同時發送一些請求,以查看更多greelet的打印輸出。
  • 您的示例在使用chromeMac上運行時,bottle docs指出您可能需要在某些瀏覽器上產生更多字節:

    注意 :某些瀏覽器在開始呈現頁面之前會緩沖一定數量的數據。 您可能需要產生多個字節才能在這些瀏覽器中看到效果。 此外,許多瀏覽器每個URL最多只能有一個並發連接。 在這種情況下,您可以使用第二個瀏覽器或基准工具(例如ab或httperf)來衡量性能。

根據瓶裝文檔,是否不應該在每次執行time.sleep()時生成一個新的greenlet實例?

否。恐怕瓶子的文檔有些混亂。

為每個傳入的HTTP請求生成一個新的greenlet。 然后,生成的greenlet從頭到尾處理整個請求。 如果那個greenlet產生了(顯式或隱式),那么另一個greenlet可以自由地做一些工作(大概處理其他HTTP請求)。

當你調用monkeypatched time.sleep ,正在處理您的HTTP請求的greenlet被暫停,由此產生的任何其他活動的greenlets(如果有的話)。 time.sleep返回(在指定的秒數后)時,您的Greenlet(與之前為您的請求提供服務的那個Greenlet相同)被喚醒,並從sleep調用后恢復運行。

希望有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM