多執行緒與協程爬蟲

2021-09-29 05:24:39 字數 2542 閱讀 6997

網路爬蟲是一種高io密集型任務,所以傳統的程序或者多程序並不適合網路爬蟲。雖然由於cpython中全域性直譯器鎖gil的存在,無法真正意義上的實現多執行緒,但這種「不完美的多執行緒」依然可以大大提高爬蟲效率,當然在提高爬蟲效率方面還有大家所熟知的協程。

比較官方的介紹我就不說了,畢竟瞅了一眼一大串,這個快節奏的時代相信也沒有多少人看到下去,哈哈。

簡單的講,如果把乙個程序看成乙個空間,那麼多程序就是多個可以互相隔離的並行空間,而多執行緒則是在乙個程序空間中開闢出多個並行的執行緒,這也就意味著多個執行緒間是共享資源的,因此多執行緒相比於多程序的資料安全性更低,這也是cpython引入gil的原因。那麼如何理解協程呢,事實上,多執行緒的本質是在乙個程序的基礎上實現高併發,而協程則是在乙個執行緒的基礎上實現高併發,協程的排程是通過**來實現的,而不是cpu。(還是寫了一大串哈)

from gevent import monkey;monkey.patch_all() 

from lxml import etree

from concurrent.futures import threadpoolexecutor

import requests

import time

import gevent

"""設定乙個計算函式執行時間的裝飾器"""

"""實現單程序/單執行緒爬蟲類

"""繼承自父類baiduspider,實現多執行緒

"""def __init__(self):

super().__init__()

self.tpool = threadpoolexecutor(max_workers=20) # 設定執行緒池中允許通過的執行緒數量

"""繼承自父類baiduspider,實現多協程

"""def __init__(self):

super().__init__()

def run(self, page):

a_list =

for i in range(page):

pn = i * 10

g = gevent.spawn(self.schedule, pn)

for i in a_list:

i.join()

if __name__ == '__main__':

# a = baiduspider() # 單程序/單執行緒當前用時3.900386333465576

# a.run(6)

# b = threadbaidu() # 多執行緒當前用時0.8708631992340088

# b.run(6)

c = asyncbaidu() # 多協程當前用時0.8858425617218018

c.run(6)

協程與執行緒

reference 協程不只在go語言中實現了,其實目前大部分語言都實現了自己的一套協程,包括c erlang python lua j ascript ruby等。相對於協程,你可能對程序和執行緒更為熟悉。程序一般代表乙個應用服務,在乙個應用服務中可以建立多個執行緒,而協程與程序 執行緒的概念不一...

協程的多執行緒切換

我們知道,在乙個基於協程的應用程式中,可能會產生數以千記的協程,所有這些協程,會有乙個的排程器來統一排程。另外我們知道,高效能的程式首要注意的就是避免程式阻塞。那麼,在以協程為最小執行單位的程式中,同樣也需要確保這一點,即每乙個協程都不能發生阻塞。因為只要某乙個協程發生了阻塞,那麼整個排程器就阻塞住...

協程的多執行緒切換

我們知道,在乙個基於協程的應用程式中,可能會產生數以千記的協程,所有這些協程,會有乙個的排程器來統一排程。另外我們知道,高效能的程式首要注意的就是避免程式阻塞。那麼,在以協程為最小執行單位的程式中,同樣也需要確保這一點,即每乙個協程都不能發生阻塞。因為只要某乙個協程發生了阻塞,那麼整個排程器就阻塞住...