用最簡(jiǎn)單的辦法寫(xiě)多線程的程序
python的多線程由于GIL鎖的緣故,不能有效利用CPU多核,但是在I/O密集型的任務(wù)中,多線程仍然可以有效的提高程序的性能。你可以自己從頭編寫(xiě)多線程的程序,也可以使用已經(jīng)封裝好的庫(kù),前者可以讓你更加熟悉理解如何編寫(xiě)多線程程序,后者可以讓你快速完成任務(wù),達(dá)到自己的目標(biāo)。
今天給大家推薦一個(gè)非常好用的庫(kù),concurrent,在2.7的版本中,它還是第三方庫(kù),但3.x之后,已經(jīng)被官方納入正式版本,可見(jiàn)這個(gè)庫(kù)是多么優(yōu)秀。使用concurrent編寫(xiě)多線程代碼,可以節(jié)省大量時(shí)間,尤其是對(duì)于結(jié)果的收集,簡(jiǎn)直太便利了。下面的代碼,演示如何用concurrent 來(lái)實(shí)現(xiàn)一個(gè)多線程的爬蟲(chóng)程序。
import requestsfrom concurrent.futures import ThreadPoolExecutorurls = ['http://www.baidu.com', 'http://www.zhihu.com', 'http://www.csdn.net']def web(url):res = requests.get(url)return url, res.status_codeexecutor = ThreadPoolExecutor(max_workers=3)for url, status_code in executor.map(web, urls):print(url, status_code)
我們只需要關(guān)注在單個(gè)線程里需要做什么事情就可以了,就比如我寫(xiě)的web函數(shù),只關(guān)心如何爬取一個(gè)url,其他的事情,諸如線程池如何創(chuàng)建,爬取的結(jié)果如何從子線程返回至主線程,統(tǒng)統(tǒng)不用考慮。
max_workers 指定了線程池的大小,executor.map 需要傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是子線程里需要執(zhí)行的函數(shù),第二個(gè)參數(shù)是一個(gè)列表,列表里是需要傳入函數(shù)的參數(shù),看起來(lái)很簡(jiǎn)單吧!
