io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程
圖/文:迷神
我們在Python爬蟲中,重要的是講究速度,如果有10萬或者100萬Url地址,寫過爬蟲的都會知道,那估計是非常慢的。我們的Python爬蟲一般IO密集型業務,Python爬蟲程序需要發起網絡請求,必然就有網絡IO阻塞,通常請求一個URL耗時要幾百毫秒到幾秒,逐步執行,和我們CPU那么高性能比起來,那真是天壤之別。
比如,我們Python爬蟲在單線程同步爬取過程中,一個個的爬取網站所有的URL,假設100個URL,平均每個URL請求的時間是1秒,那么在單線程同步場景下,最快也需要100秒鐘,才能把所有的頁面爬取下來。
在網頁數據爬取以后,發現在數據量不大的時候,這種普通的程序還勉強,如果想極大提高速度,做到 快速爬蟲,就需要使用多線程,多進程,異步IO編程了。不過,Python中有一個臭名昭著的GIL,導致做不到真正的并行運算,多核無法真正利用起來。多線程在切換線程,還有切換成本,以及線程的創建成本。如果使用多進程,雖然能利用多核處理的優勢,但是多進程的創建本城比線程更高,而IO密集型任務,CPU不是瓶頸。
鑒于此,Python3.4 還是引入了異步 asyncio 模塊,增加了異步編程,跟 JavaScript 的async/await 極為類似,大大方便了異步任務的處理。異步編程使得CPU不再需要再去等待耗時的操作,而是讓出CPU時間給其他任務執行,可以極大提高完成所有的任務速度。
下面,我們通過具體的小例子,來看看多線程,多進程,異步IO編程的區別:
1、普通同步,單線程阻塞
單線程版本,所有的任務,按照順序依次等待執行。
單線程
結果如下:
結果
可以發現,總共5個任務,他們每個任務執行時間是1秒鐘,單進程阻塞時,總共耗時是5秒多一點點。
2、多線程版本任務
簡單來說就是在一個進程里面,可以執行多個任務,在這里的每一個任務就是一個線程。
多線程任務
執行結果:
執行結果
換成多線程之后,5個線程各負責一個任務。我們看到執行結果:1.0039010047912598 已經明顯比第一個快很多了。即使有GIL
多進程版本任務
多進程就是你的電腦允許運行多個程序,在同一段時間里面,可以 “同時” 執行多個任務。
多進程版本
執行結果:
直接結果
執行結果:1.7484214305877686。是不是很奇怪,使用多進程,時間比多線程更慢,為什么?因為創建進程的成本是要比線程高的,雖然,它可以利用多核CPU的優勢。
異步版本多個任務
最后,我們來看看異步模式下,怎么樣。
異步
執行結果:
執行結果
發現使用asyncio所花的時間是最少的。asyncio可以實現單線程并發IO操作,它沒有多線程和進程的創建成本,就是在單線程環境下,切換任務,當這個任務被阻塞時,立刻切換其他任務,當前面的任務完成時,在通知它,這樣效率就極大的提高了。
最后,值得一說的就是一個不錯的HTTP框架:aiohttp,它是一個基于asyncio實現的非常強大的HTTP框架,很值得學習哦。
總結
以上是生活随笔為你收集整理的io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 商品房高评高贷指什么?
- 下一篇: linux测试手柄,Linux Joys