江湖小白之一起學Python (七)多線程的運用

清晨起來,陽光明媚,不由自主的看看了自己的私房錢……目前疫情還未結束,不過看大家基本都回歸了正常了的生活,再大的疫情及困阻都無法阻擋我對上班的熱情(向錢進~~!)

爬蟲中常用的多線程,多進程,協程等等,今天我們就來說下這個多線程的基本運用,這時候小白可能會問,啥是多線程啊,有啥用啊?客官勿慌,請聽在下給你娓娓道來……

我們就拿一個理髮店來說,理髮店有4個理髮師傅,由於跟我一樣上進的人比較多,一堆人早早的就起來排隊理髮了,但這個時候就只有1個師傅在店裏,那我們這一堆人就排隊等着這個師傅一個一個的理髮,過了一段時間剩下的3個師傅也來了,那就同時一下可以4個一起理髮,是不是縮短了大家的等待時間,ALL RIGHT!就是這個道理,嗯,我感覺我是明白了,OK, 沒明白的沒關係,咱們繼續……

下面我就寫一個簡單的例子來說明,首先我們定義一個方法:

def run(n):
    time.sleep(1)
    print("我是方法:{}".format(n))

這個方法裏time.sleep(1)是延遲1秒執行下面的打印,目的是爲了方便觀察執行的結果。

我們先來個正常情況下執行循環打印0-9的方法,看看所需要的時間是多少:

#開始時間
begintime=time.time()
for i in range(10):
    run(i)
#結束時間
endtime=time.time()
print("執行時間:{}".format(endtime-begintime))

在執行前定義下開始時間,在循環結束定義下結束時間,然後打印看下這個過程花費的時間,來,我們看下結果:

整個過程花了差不多10秒鐘的時間,我們改動一下,加入多線程的方法:

#開始時間
begintime=time.time()
for i in range(10):
    t=threading.Thread(target=run, args=(i,))
    t.start()
#結束時間
endtime=time.time()
print("執行時間:{}".format(endtime-begintime))

這裏說明一下,python的多線程首先要引入threading庫,threading.Thread這個是調用線程的方式,裏面有許多參數,常用的就是上面這個2個基本參數,target=run是條調用上面定義的run()的方法,這裏不需要括號和參數,參數放在後面 args=(i,),這裏爲什麼要這樣寫呢,因爲run只有一個參數,args是以數組或元組的形式傳遞的,如果不加逗號,python解釋器認爲你傳遞是個數字而不是數組或者元組的格式,會報錯……接着我打印看下上面執行的時間:

看到沒,不要驚訝,這個過程只耗時0.002秒,算算正常執行的時間是它的多少倍,這就是多線程的奧妙之處,這裏有個伏筆,繼續往下看,細心的小白可能發現輸出的內容不是按0-9依次展示的,不錯,善於觀察,正常的for循環是依次有序的執行,而線程是並行執行的,什麼是並行,就是同時執行不一樣的任務。

裏面常用的設置還有很多,簡單說下下面2個參數:

t.setDaemon(True)   #這個是設置守護線程,意思就是主線程不等待子線程全部完成就執行後面的代碼,反之亦然
t.join()      #這個表示主線程會等待子線程執行完畢後繼續往下執行

想了解更多參數可以去看看threading庫的詳細介紹,一般情況下只會用到上面所說的,來我們改動下代碼看看join的用法:

#開始時間
begintime=time.time()
#定義一個線程池
thread_pool = []
for i in range(10):
    t=threading.Thread(target=run, args=(i,))
    t.start()
    thread_pool.append(t)

for i in thread_pool:
    i.join()
#結束時間
endtime=time.time()
print("執行時間:{}".format(endtime-begintime))

我們定義一個線程池,首先將要執行的線程放入到線程池裏,我們循環線程池,加入join(),打印看看:

這時候細心的小白可能就要問了,,上面的執行時間爲什麼0.002秒,這裏爲什麼是1秒,而且執行時間顯示的位置也不一樣,一個在第一行,一個在最後一行,沒錯,原因其實就在這裏,0.002秒的方法是因爲直接執行的子線程,我們開始沒有加入join(),運行文件後,主線程是不會等待子線程執行完成後再退出的,所以這個時間只是腳本執行的完成的時間,並不包含子線程運行的時間,加入join()後,打印的執行時間就包含了子線程的運行時間,所以真正的總耗時間爲1秒,這就是用了多線程和沒用多線程的區別。

好了,關於多線程的用法基本也就講到這裏,有興趣的童鞋可以用我講的第一章抓取小說網的例子,加入多線程的運用,實現天下小說任君採的境界……

白嫖兄弟們,源碼雙手奉上:

#coding:utf-8
import threading,time

def run(n):
    time.sleep(1)
    print("我是方法:{}".format(n))

#開始時間
begintime=time.time()
thread_pool = []
for i in range(10):
    t=threading.Thread(target=run, args=(i,))
    t.start()
    thread_pool.append(t)

for i in thread_pool:
    i.join()
#結束時間
endtime=time.time()
print("執行時間:{}".format(endtime-begintime))

我就是我,油膩而不失帥氣的我,江湖不說再見,咱們下篇見!

關注公衆號,發現不一樣的自我

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章