到目前為止,實(shí)際上我們的爬蟲(chóng)進(jìn)程總共介紹了:
爬蟲(chóng)架構(gòu)——確認(rèn)目標(biāo)(爬蟲(chóng)對(duì)象)——分析網(wǎng)頁(yè)(抓包分析,URL咋變的,什么參數(shù)?)——請(qǐng)求網(wǎng)頁(yè)(requests庫(kù))——解析網(wǎng)頁(yè)(bs4,lxml)——提取內(nèi)容(xpath,css selector,re,find,find_all)——封裝內(nèi)容(轉(zhuǎn)json,轉(zhuǎn)dict)——本地寫(xiě)入(txt,csv,json,html)——入庫(kù)(mysql)——可視化繪圖(pyecharts)的整個(gè)簡(jiǎn)單流程。
而在上一篇說(shuō)的是,
python3爬蟲(chóng)系列13之find_all爬蟲(chóng)高考分?jǐn)?shù)線(xiàn)并繪制分析圖(普通版),
在網(wǎng)頁(yè)數(shù)據(jù)爬取以后,發(fā)現(xiàn)在數(shù)據(jù)量不大的時(shí)候,這種普通的程序依然速度很慢,那么想要做到 快速爬蟲(chóng),就需要知道
使用它們,進(jìn)程、單進(jìn)程、多進(jìn)程、線(xiàn)程、單線(xiàn)程、多線(xiàn)程、并行、并發(fā)、互斥鎖、協(xié)程。往往可以 讓我們的爬蟲(chóng)程序加速?zèng)_刺。
進(jìn)程就是正在運(yùn)行的程序
比如你的電腦系統(tǒng)現(xiàn)在正在運(yùn)行著的QQ(酷狗,微信啥子隨便了。)就是一個(gè)進(jìn)程。
一旦你的「QQ」運(yùn)行起來(lái),系統(tǒng)就會(huì)給「QQ」分配了內(nèi)存和資源。
進(jìn)程和進(jìn)程之間是互相獨(dú)立的,分配的空間也不交集。
單進(jìn)程就是你的電腦太破,只允許運(yùn)行一個(gè)程序。其他的運(yùn)行就炸。
簡(jiǎn)單來(lái)說(shuō)就是電腦只能做一件事情.比如電腦打開(kāi)了QQ,就不能再去打開(kāi)淘寶。
多進(jìn)程就是你的電腦允許運(yùn)行多個(gè)程序,在同一段時(shí)間里面
可以 “同時(shí)” 執(zhí)行多個(gè)任務(wù)。
簡(jiǎn)單來(lái)說(shuō)就是電腦可以同一時(shí)間在做很多事情,一邊玩聽(tīng)歌一邊看片。
原理就是你的CPU 在做進(jìn)程之間的切換,因?yàn)镃PU 的切換速度超級(jí)快,快到讓你感覺(jué)到,開(kāi)著的所有程序好像是在同時(shí)運(yùn)行。
這樣就提高了 CPU 的使用率了,所有代碼后期都愛(ài)提及多進(jìn)程。同理你的爬蟲(chóng)就可以使用多進(jìn)程。
線(xiàn)程是比進(jìn)程更小的一個(gè)單位,可以說(shuō)是程序用 CPU 的一個(gè)基本單元。它存在于進(jìn)程之中,而且有很多兄弟伙。
簡(jiǎn)單來(lái)說(shuō)就是在一個(gè)進(jìn)程里面,可以執(zhí)行多個(gè)任務(wù),在這里的每一個(gè)任務(wù)就是一個(gè)線(xiàn)程。
單線(xiàn)程是一個(gè)程序里,如果只是單一的一個(gè)執(zhí)行路徑,那么它就是單線(xiàn)程的。就是什么,你是個(gè)獨(dú)生子。
簡(jiǎn)單來(lái)說(shuō)就是在一個(gè)進(jìn)程里面,要執(zhí)行多個(gè)任務(wù),但是呢,完成任務(wù)的方式只有一個(gè)單一的執(zhí)行路徑,那么它就是單線(xiàn)程的。
單線(xiàn)程是一個(gè)程序里,如果只是單一的一個(gè)執(zhí)行路徑,那么它就是單線(xiàn)程的。就是什么,你是個(gè)獨(dú)生子。
簡(jiǎn)單來(lái)說(shuō)就是在一個(gè)進(jìn)程里面,要執(zhí)行多個(gè)任務(wù),但是呢,完成任務(wù)的方式有多個(gè)執(zhí)行路徑,那么它就是多線(xiàn)程的。
So:
想要讓爬蟲(chóng)更高效,就可以讓你的爬蟲(chóng)實(shí)現(xiàn)多線(xiàn)程。
既然說(shuō)到了線(xiàn)程,自然離不開(kāi)并行和并發(fā)。
在某一個(gè)【時(shí)間段內(nèi)】,可以同時(shí)執(zhí)行多個(gè)進(jìn)程,這就是并行。
簡(jiǎn)單來(lái)說(shuō),一個(gè)單核的 CPU每次只能執(zhí)行一個(gè)進(jìn)程,那么一個(gè)多核的 CPU,就可以同時(shí)執(zhí)行多個(gè)進(jìn)程了。這樣這些同時(shí)運(yùn)行的多個(gè)進(jìn)程,就是一種并行方式。
在某一個(gè)【時(shí)間點(diǎn)】,同時(shí)執(zhí)行多個(gè)進(jìn)程,這就是并發(fā)。
簡(jiǎn)單來(lái)說(shuō)就是 在 雙十一的時(shí)候,晚上的 12 點(diǎn),大伙的女朋友們都在握著手機(jī),準(zhǔn)備同時(shí)秒殺某一個(gè)商品。這個(gè)多人一起搶一個(gè)東西,就是一種并行方式。
保安,讓線(xiàn)程別他媽亂來(lái),排好隊(duì),一個(gè)一個(gè)線(xiàn)程安全有序的去執(zhí)行。
在系統(tǒng)里面,進(jìn)程和進(jìn)程之間是互相獨(dú)立的,而我們知道,一個(gè)進(jìn)程里面有多個(gè)線(xiàn)程,而線(xiàn)程之間卻是共享一個(gè)進(jìn)程空間的。
簡(jiǎn)單來(lái)說(shuō),
你想啊,一個(gè)蛋糕好多個(gè)線(xiàn)程一起分,勞資又不是恐龍,誰(shuí)都不讓?zhuān)y免就有一些線(xiàn)程就要搞事情了。
于是好多線(xiàn)程都暴動(dòng)了,這樣數(shù)據(jù)就不安全了,所以就有了互斥鎖的出現(xiàn)。
它的作用就是讓線(xiàn)程別他媽亂來(lái),排好隊(duì),一個(gè)一個(gè)線(xiàn)程安全有序的去執(zhí)行。
很多開(kāi)發(fā)語(yǔ)言中都有這個(gè)互斥鎖的存在。名字可能不一樣喲。
有了互斥鎖的出現(xiàn),python中取了個(gè)別名叫GIL :全稱(chēng)是 Global Interpreter Lock(全局解釋器鎖)。
就是用來(lái)控制線(xiàn)程執(zhí)行權(quán)限的,線(xiàn)程需要執(zhí)行的時(shí)候,要先獲得 GIL 之后才可以執(zhí)行,這樣就不會(huì)產(chǎn)生線(xiàn)程安全問(wèn)題。
這東西設(shè)計(jì)之初的考慮,為了數(shù)據(jù)安全所做的決定。某個(gè)線(xiàn)程想要執(zhí)行,必須先拿到 GIL,我們可以把 GIL 看作是“通行證”,并且在一個(gè)
Python 進(jìn)程中,GIL 只有一個(gè)。拿不到通行證的線(xiàn)程,就不允許進(jìn)入 CPU 執(zhí)行。
so:
在 Python 中,無(wú)論是單核還是多核,都同時(shí)只能有一個(gè)線(xiàn)程在執(zhí)行。其根源就是因?yàn)?GIL 鎖的存在。
相比python,其他語(yǔ)言(比如java)CPU 是多核時(shí)是支持多個(gè)線(xiàn)程同時(shí)執(zhí)行。尷尬了。
上面我們知道了在python中因?yàn)?GIL 鎖,我們同時(shí)只能有一個(gè)線(xiàn)程在執(zhí)行。
這意味著多線(xiàn)程還有個(gè)毛用???
此時(shí),python提出了另外一個(gè)特性:在 I/O 流阻塞的時(shí)候,GIL會(huì)被釋放。(GIL被炒魷魚(yú)了)
(所謂I/O流就是輸入輸出流)
什么意思呢?
就是說(shuō)以后你寫(xiě)Python 程序:
如果是要處理一些【輸入輸出的多任務(wù)】,在 I/O 流阻塞的時(shí)候,GIL會(huì)被釋放,相對(duì)于GIL被炒魷魚(yú)了,就可以開(kāi)啟多線(xiàn)程。
如果是要處理【多任務(wù)】,想要充分的去利用我們多核的CPU,就開(kāi)啟多進(jìn)程。因?yàn)閷?duì)于頻繁的cpu操作,由于GIL鎖的原因,多個(gè)線(xiàn)程只能用一個(gè)cpu,這時(shí)多進(jìn)程的執(zhí)行效率要比多線(xiàn)程高。
協(xié)程也叫微線(xiàn)程。
在一個(gè)線(xiàn)程里面可以執(zhí)行多個(gè)函數(shù),線(xiàn)程和進(jìn)程是通過(guò)系統(tǒng)調(diào)度的(也就是函數(shù)之間由系統(tǒng)來(lái)自行調(diào)度,開(kāi)銷(xiāo)?。?/font>
而協(xié)程(微線(xiàn)程)不需要通過(guò)系統(tǒng)調(diào)度,可以根據(jù)需要自己調(diào)度。(因?yàn)槲⒕€(xiàn)程是函數(shù)之間在切換,所以開(kāi)銷(xiāo)更小)。在 python 中使用微線(xiàn)程時(shí)一般會(huì)用到 (genvent、monkey.patch_all)
最后
python什么時(shí)候使用多線(xiàn)程,什么時(shí)候使用多進(jìn)程?
多線(xiàn)程使用場(chǎng)景:IO密集型- 輸入輸出處理(頻繁讀取文件,讀取網(wǎng)絡(luò)套接字),大多時(shí)間是在等待。io 操作不占用CPU(從硬盤(pán)、從網(wǎng)絡(luò)、從內(nèi)存讀數(shù)據(jù)都算io,網(wǎng)絡(luò)并發(fā)這一類(lèi)的。
多進(jìn)程使用場(chǎng)景:CPU密集型-絕大多數(shù)時(shí)間在數(shù)學(xué)與邏輯運(yùn)算,比如批量爬取很多數(shù)字,文本數(shù)據(jù),求平均值,數(shù)據(jù)分析等。
小提示:Python中 time.sleep 是阻塞的,都知道使用它要謹(jǐn)慎,但在多線(xiàn)程編程中,time.sleep 并不會(huì)阻塞其他線(xiàn)程。使用os.system(‘pause’)
聯(lián)系客服