Re: [心得] 爬蟲實做分享

看板Python作者 (←這人是超級笨蛋)時間8年前 (2017/03/27 22:35), 8年前編輯推噓1(100)
留言1則, 1人參與, 最新討論串3/3 (看更多)
※ 引述《zerof (貓橘毛發呆雕像)》之銘言: ※ 引述《zerof (貓橘毛發呆雕像)》之銘言: : 這疑慮是對的, L:48 的 for-loop 的確會導致 L:54 接近循序執行,在 scheduler : 沒滿的情況下的確會比較慢。 : 這部份的考量主要在於 L:54 request 的是主網站而非圖床,避免大量 requests : 導致其他使用者的延遲。 : L:64 則是大量 requests 會導致 WinSock 炸掉.... http://imgur.com/zA94lRJ
, : 只好加個 limit 再用 wait() 來跑 。 (它炸太快我也不知道上限到底是多少....) : 這裡一樣的問題是 async.wait() 會 block 到所有的 task done 才跑下一輪,在某 : 種意義上 scheduler 也是沒有滿的狀態。 這個技巧叫做 throttling,是這個問題的解法沒錯 但與其手動 delay,更好的方法是直接限制同時可以有幾個 tasks 最簡單的方法是加上一個 semaphore: semaphore = asyncio.Semaphore(CONCURRENT_TASK_COUNT) async def throttle(f): async with semaphore: await f await asyncio.wait([throttle(f) for f in fs]) 只要調整 CONCURRENT_TASK_COUNT 就可以保證 wait 一次只會同時等這麼多個 tasks 前面 fetch_imgs 部分也可以類似處理

03/27 21:07,
其實這個例子比較好用 threading 就好,之前 pyCon 有講
03/27 21:07

03/27 21:07,
說 requests 在做檔案 IO 時好像放掉 GIL?
03/27 21:07
: 這蠻有趣的XD, requests 下層的 library 是用 urllib3 是 native python 寫的, : 相依性是零,有 connectionpool ,沒猜錯的話是用 threading pool 。 : 而實際上 GIL 在呼叫用 C 寫的函式的時候都會被釋放,所以在用 open 開檔案的時 : 候是一定會釋放 GIL 的。 : 就算是這樣, asyncio 實際上還是比 multithread 快,可以參考這個影片: : https://youtu.be/M8Z65tAl5l4
這邊的關鍵已經不是速度了, 前面就證明了速度太快也沒用, server hold 不住 更重要的問題是 async 加上 synchronization primitives 可讀性會快速下降 (這也是為什麼最近 reactive programming 這麼紅, 不過那是另一個議題) 在速度不那麼重要的狀況下, threading idiom 會好懂一些 -- Les grandes et les meilleurs tone from "Zadok the Priest" Eine grosse stattliche Veranstaltung by F. Handel THE MAIN EVENT! These are the men Sie sind die Besten "Champions League" by Tony Britten THESE ARE THE CHAMPIONS! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.161.19.12 ※ 文章網址: https://www.ptt.cc/bbs/Python/M.1490625319.A.738.html ※ 編輯: uranusjr (218.161.19.12), 03/27/2017 22:40:52

03/27 22:42, , 1F
Semaphore 解得蠻漂亮的XD
03/27 22:42, 1F
文章代碼(AID): #1OsICdSu (Python)
文章代碼(AID): #1OsICdSu (Python)