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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python twisted教程 二:缓慢的诗

發(fā)布時間:2025/3/15 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python twisted教程 二:缓慢的诗 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我的假設(shè)

我假設(shè)你已經(jīng)有一些基本的能力去寫python程序,并且直到一些socket編程方面的額知識,如果你沒有接觸過socket請移步這里 socket module documention, 這個系列中的代碼例子都是運行在python2.5 和twisted 8.2.0,程序如果不能正確運行請檢查你的python和twisted 的版本.

獲取例子代碼

你可以在public git repository獲取例子代碼,如果你可以用git 或者其他的版本管理軟件,你可以直接clone 出一份代碼:

git clone git://github.com/jdavisp3/twisted-intro.git

緩慢的詩

盡管cpu比網(wǎng)絡(luò)要快很多,但是網(wǎng)絡(luò)還是仍舊會比你的腦袋或者眼睛快.所以你要看到cpu-network是怎樣運行幾乎是不可能的.我們需要的是一個slow server,可以讓我們的眼睛看到變化.既然是一個server,那就讓我們的server來生產(chǎn)兩首頗具詩意的詩吧,在代碼倉庫的子目錄中有John Donne, W.B. Yeats, 和 Edgar Allen Poe 的三首小詩,當(dāng)然如果換成你自己寫的,that will be nice :)
最基本的”poetry server” 的實現(xiàn)在 blocking-server/slowpoetry.py,你可以讓他跑起來:

python blocking-server/slowpoetry.py poetry/ecstasy.txt

上面這個命令會開啟一個阻塞的服務(wù)器,你可以打開這個阻塞服務(wù)器的源碼看一下,你可以看到我們并沒有用到twisted,只有一些簡單的socket 操作.它可以在每個固定的延遲后發(fā)出固定的數(shù)量的字節(jié),默認(rèn)的它會每0.1s 發(fā)出10個字節(jié).你可以通過–num-bytes 和 –delay 來控制時間和字節(jié)數(shù),比如下面:

python blocking-server/slowpoetry.py --num-bytes 50 --delay 5 poetry/ecstasy.txt

當(dāng)這個服務(wù)開始運行的時候,它會打印出它監(jiān)聽的端口.默認(rèn)的,這個是一個隨機的端口,你可以通過修改配置讓它監(jiān)聽固定的端口,你可以指定它監(jiān)聽的端口如下:

python blocking-server/slowpoetry.py --port 10000 poetry/ecstasy.txt

如果你有netcat 命令的話,你可以測試這個server 通過一下的命令:

netcat localhost 10000

如果一切正常的話,你會看到一條小詩被每次輸出一些字節(jié),一旦這首小詩被完全生產(chǎn)出來,服務(wù)器會斷開連接.

如果你看源碼的話你會發(fā)現(xiàn),poetry server 不僅僅是每次輸出一些字節(jié),如果你再用其他的client去連接server 的話,其他的client 必須等到第一個client被處理完才會被poetry server 處理. 現(xiàn)在的poetry server 確實很慢啊,慢的我蛋痛.

阻塞的client
在我們的例子中我們的客戶端也是阻塞的,它可以從多個server 上一個接一個的讀取內(nèi)容,現(xiàn)在我們給我們的客戶端三個任務(wù)去執(zhí)行,就想圖片一中的那樣.首先我們先啟動三個服務(wù)器,為三個不同的客戶端來服務(wù),如下:

python blocking-server/slowpoetry.py --port 10000 poetry/ecstasy.txt --num-bytes 30
python blocking-server/slowpoetry.py --port 10001 poetry/fascination.txt
python blocking-server/slowpoetry.py --port 10002 poetry/science.txt

接下來我們可以開啟阻塞的客戶端blocking-client/get-poetry.py來接收小詩了:

python blocking-client/get-poetry.py 10000 10001 10002

客戶端會按照順序的去接收小詩,只有接收完一個才會去接收下一個.你會看到一下的輸出:

Task 1: get poetry from: 127.0.0.1:10000
Task 1: got 3003 bytes of poetry from 127.0.0.1:10000 in 0:00:10.126361
Task 2: get poetry from: 127.0.0.1:10001
Task 2: got 623 bytes of poetry from 127.0.0.1:10001 in 0:00:06.321777
Task 3: get poetry from: 127.0.0.1:10002
Task 3: got 653 bytes of poetry from 127.0.0.1:10002 in 0:00:06.617523
Got 3 poems in 0:00:23.065661

基本上就是圖片一的文字版本.你可以看一下源代碼去定位一下在接收和發(fā)送字節(jié)的時候那些地方會產(chǎn)生阻塞.

異步的client
下面讓我們看看一個簡單的異步的client,沒有用twisted.先讓我們運行一下, async-client/get-poetry.py:


python async-client/get-poetry.py 10000 10001 10002

你將會得到如下的輸出:

Task 1: got 30 bytes of poetry from 127.0.0.1:10000
Task 2: got 10 bytes of poetry from 127.0.0.1:10001
Task 3: got 10 bytes of poetry from 127.0.0.1:10002
Task 1: got 30 bytes of poetry from 127.0.0.1:10000
Task 2: got 10 bytes of poetry from 127.0.0.1:10001
...
Task 1: 3003 bytes of poetry
Task 2: 623 bytes of poetry
Task 3: 653 bytes of poetry
Got 3 poems in 0:00:10.133169

這一次的輸出結(jié)果會比較長因為每當(dāng)異步的client 每一次從任何一個服務(wù)器上獲取一些東西都會輸出.注意,這個異步的client 會交錯的執(zhí)行三個任務(wù),就像在圖片三中描述的那樣.

需要注意的是,異步客戶端完成任務(wù)用了差不多10s,而同步的客戶端需要差不多23s,現(xiàn)在回想一下圖片三和圖片四的區(qū)別.通過減少阻塞的時間,我們的異步客戶端需要更少的時間.我們的異步的客戶端也是會有一些阻塞,但通過交錯任務(wù)來執(zhí)行可以減少很多阻塞的時間.

嚴(yán)格的來說,我們的異步client也在執(zhí)行阻塞操作:它會向stdout輸出一些內(nèi)容.但對我們的例子還沒有太大的影響.終端其實一直在準(zhǔn)備接收更多的print 的輸出,所以print 并不會阻塞,和我們的slow 服務(wù)器來說,print語句很快.如果我們的異步程序是一個進(jìn)程中管道的一部分,在處理標(biāo)準(zhǔn)的輸入和輸出的時候應(yīng)該考慮用異步的I/O.twisted 已經(jīng)提供了在處理標(biāo)準(zhǔn)輸入輸出時異步I/O 的支持,為了kiss 原則,這里先不用

更進(jìn)一步的
讓我們看一下異步client 的代碼,注意異步client代碼和同步client代碼的區(qū)別:

????異步的client會一次連接多個server,而同步的client
????異步的client中的socket 通過setblocking(0)設(shè)置為了非阻塞的
????select 模塊的selsect可以用來監(jiān)聽是否有socket可以提供給client 的數(shù)據(jù)
????從服務(wù)器讀數(shù)據(jù)的時候,異步client會盡可能的多讀數(shù)據(jù)直到這個socket被阻塞,然后如果有其他的socket是可讀的話就轉(zhuǎn)到下一個,這意味著我們必須要記錄每一首小詩傳輸狀態(tài)

這個異步client 中最核心的部分是get_poetry 函數(shù)的上層的事件循環(huán),這個循環(huán)要經(jīng)過一下的過程:

????用select監(jiān)聽所有打開的sockets,直到其中的一個socket有數(shù)據(jù)流可以讀
????如果有一個socket有數(shù)據(jù)可讀,讀取它
????重復(fù)循環(huán),直到所有的socket都關(guān)閉

同步的client在main 函數(shù)中也有一個循環(huán),但是每次遍歷的時候同步客戶端只下載同一首小詩,直到這首小詩讀完.而異步的client在每次循環(huán)的時候會讀取多個小詩的片段,我們不確定在一次循環(huán)中他會讀取幾個小詩,或者每次讀取多少字節(jié), 這完全依賴于服務(wù)器的速度以及網(wǎng)絡(luò)的速度.我們讓select 告訴我們哪一個socket有數(shù)據(jù)可以讀,然后我們就可以在不產(chǎn)生阻塞的情況下盡可能多的去讀數(shù)據(jù)了.

假如一個同步的client一直連在一個相同的服務(wù)器上(讓我們假設(shè)是三號服務(wù)器),它現(xiàn)在根本不需要一個外部的循環(huán),因為get_poety函數(shù)是阻塞的,客戶端會一直連在同一個server上,直到獲取完整個的一首詩.而異步的客戶端沒有一個事件循環(huán)的話則無法進(jìn)行下去,異步的客戶端需要在一開始的就監(jiān)聽全部的socket,然后在每一次的循環(huán)中處理所能收受的所有數(shù)據(jù).

這種用一個循環(huán)去等待事件的發(fā)生,然后去處理事件的模式我們很常見,已經(jīng)形成了一種設(shè)計模式叫做:reactor pattern(反應(yīng)堆模式),下面這張圖比較直觀的描述了反應(yīng)堆模式



the reactor loop

這個循環(huán)就是一個反應(yīng)器因為他在不斷的等待事件的發(fā)生然后響應(yīng)他們,因為這個原因也被叫做事件循環(huán).因為”反應(yīng)器”系統(tǒng)總是等待I/O,這些循環(huán)有時也被叫做 select loops,select call 也經(jīng)常等待I/O. 在一個select loop 中,一個事件就是其中一個socket 變?yōu)榭勺x的或者可寫的.記住 select 不是等待I/O 的唯一的方法,還有其他的方法被用做等待I/O(比如epoll),他們甚至比select 的性能要好,拋開性能不說,他們都用來做同一件事情:監(jiān)聽一些端口,然后等待其中的一些端口可以讀或者可以寫.

用select來監(jiān)測文件描述符來實現(xiàn)一個簡單的非阻塞程序是可能的,在" 反應(yīng)器系統(tǒng)中"執(zhí)行一些不涉及I/O的操作也是可以的.但是在一個真正的反應(yīng)器系統(tǒng)中,所有的工作都是I/O相關(guān)的

嚴(yán)格的來,咱們的異步client 不是” 反應(yīng)堆模式”,因為循環(huán)的邏輯和也業(yè)務(wù)邏輯沒有完全分開,他們交錯在一起.一個真正的反應(yīng)器模式應(yīng)該讓事件循環(huán)作為一個抽象來實現(xiàn)以下兩點:

????1,接收一些你要處理I/O的文件描述符
????2,當(dāng)任何一個文件可以讀或者可以寫的時候,獨立的告訴你

一個非常好的反應(yīng)堆模式還應(yīng)實現(xiàn):

????可以處理各種操作系統(tǒng)各種奇怪的實現(xiàn)
????提供一個非常好的抽象的實現(xiàn)去幫助你很容易的去應(yīng)用reactor
????提供各種公開的協(xié)議的實現(xiàn)

好吧,其實我們想說的就是twisted,一個具有魯棒性很強,跨平臺的,包羅萬象的反應(yīng)器模式的實現(xiàn).第三部分我們將開始寫一些簡單的twisted 代碼了.ARE YOU READY?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的python twisted教程 二:缓慢的诗的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。