什么是多執行緒
這里就不說什么高深莫測的專業術語了,一句話,在泡澡的同時喝咖啡,也就是說在代碼中同時讓多個區域的代碼或者說函式同時運行以此達到提高效率的目的,
舉個例子
很多人學習python,不知道從何學起,
很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手,
很多已經做案例的人,卻不知道如何去學習更加高深的知識,
那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼!??¤
QQ群:623406465
比如我們有這樣一場比賽,小明和小紅在做跑步測驗,現在他們身上都要一個計時器用于計時,這是他們一個一個測驗,就像下面的代碼一樣,
import threading import time time0=time.time() def print_ming(): time.sleep(5) print('我是小明我跑完了') def print_hong(): time.sleep(3) print('我是小紅我跑完了') print_ming() print_hong() time1=time.time() print(time1-time0)
我們可以看到運行結果
顯然我們花了8秒左右的時間做完了測驗,然而他們都有一個計時器既然如此把他們同時放在一起測驗不就可以大大提高效率嗎,
同時測驗
我們打代碼做如下更改
匯入threading
1創建執行緒ming=threading.Thread(target=print_ming)
2生明執行緒ming.setDaemon(True)
3運行執行緒ming.star()
更改后的代碼如下:
import threading import time time0=time.time() def print_ming(): time.sleep(5) print('我是小明') def print_hong(): time.sleep(3) print('我是小紅') ming=threading.Thread(target=print_ming) hong=threading.Thread(target=print_hong) ming.start() hong.start() print('執行完了') time1=time.time() print(time1-time0)
結果如下:
震驚怎么可能這么快,顯然我們可以發現,在這個程式中或者測驗中,小明和小紅根本就沒有跑,怎么會這樣呢,顯然是我們的主程式運行的速度要比兩個函式(也可以是是子函式)快,所以主程式運行完了就會結束運行,
誰跑得快?
這里我們顯然需要主程式等一等我們地兩個函式,我們可以假設在做跑步測驗中有一個跑得飛快的教練,3個人當中只要有一個到達了終點,測驗就結束,所以我們先看一看讓跑的快地人等一下慢的,
所以我門在原來的基礎上加入這樣地代碼;
1創建執行緒ming=threading.Thread(target=print_ming)
2生明執行緒ming.setDaemon(True)
3運行執行緒ming.star()
4等待執行緒ming.join()
import threading import time time0=time.time() def print_ming(): time.sleep(5) print('我是小明') def print_hong(): time.sleep(3) print('我是小紅') ming=threading.Thread(target=print_ming) hong=threading.Thread(target=print_hong) ming.start() hong.start() ming.join() print('執行完了') time1=time.time() print(time1-time0)
結果如下
顯然我們知道小明怕的慢所以我們讓大家等等小明,但如果我們把ming.join()
改成hong.join()呢
顯然小明沒有執行了,所以我們必須以慢的為標準,但顯然我們有時候并不知道誰更慢,所以直接把兩個一起加進去,
并且為了方便管理我們好可以將執行緒加進回圈中,最終代碼如下;
import threading import time time0=time.time() def print_ming(): time.sleep(5) print('我是小明') def print_hong(): time.sleep(3) print('我是小紅') thread=[] ming=threading.Thread(target=print_ming) thread.append(ming) hong=threading.Thread(target=print_hong) thread.append(hong) for t in thread: t.setDaemon(True) t.start() ming.join() hong.join() print('執行完了') time1=time.time() print(time1-time0)
這里注意我沒有將join()方法加入回圈否則你會看見這樣的結果;
顯然這是沒有任何作用的,為什么會這樣呢,你可以這樣理解,回圈是在主程式中的,回圈中有兩個子程式,每一次即便兩個程式一起執行也要執行兩次,也就是說第一次小紅跑完了執行緒結束3秒,但是此時主程式未執行完進入下一個回圈這時是小明執行花費5秒共計8秒,
所以我們必須在回圈外使用join()
最終結果
import threading import time time0=time.time() def print_ming(): time.sleep(3) print('我是小明') def print_hong(): time.sleep(5) print('我是小紅') thread=[] ming=threading.Thread(target=print_ming) thread.append(ming) hong=threading.Thread(target=print_hong) thread.append(hong) for t in thread: t.setDaemon(True) t.start() ming.join() hong.join() print('執行完了') time1=time.time() print(time1-time0) #ming=threading.Thread(target=print_ming,args=(填入函式值,沒有值需要被填則不設定args引數))
tips
這個多執行緒已經說的比較清楚了,這篇博客是前兩篇有關于多執行緒的一個實體衍生,
這個代碼還是很簡單的,
爬蟲不太懂得我先前沒怎么寫完爬蟲的博客,我沒轍,
但是多執行緒這塊我講的很明白了,看不懂我也沒轍,要不然就私信有時間就回,
幾分鐘搞定python多執行緒
幾分鐘python多執行緒深入解讀
那么接下來代碼如下;
import requests from lxml import etree import threading import os from urllib import request from queue import Queue url_frist_save=Queue(1000) #url_save=Queue(200) headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'} url_root='http://pic.netbian.com' def get_url(): date_frist=requests.get(url_root,headers=headers) date_frist=date_frist.content.decode('gbk') date_frist_=etree.HTML(date_frist) uel_1=date_frist_.xpath('//li//a[@href and @title and @target]/@href')[4:] for i in uel_1: url=url_root+i url_frist_save.put(url) for i in range(2,101): urlx='http://pic.netbian.com/index_{name}.html'.format(name=str(i)) date_frist = requests.get(urlx, headers=headers) date_frist = date_frist.content.decode('gbk') date_frist_ = etree.HTML(date_frist) uel_1 = date_frist_.xpath('//li//a[@href and @target]/@href')[1:] for i in uel_1: url = url_root + i url_frist_save.put(url) def down_load(): if not os.path.exists(r'C:\Users\a3139\Desktop\projects\爬蟲dome\pictures'): os.makedirs(r'C:\Users\a3139\Desktop\projects\爬蟲dome\pictures') while True: date_frist=requests.get(url_frist_save.get(),headers=headers) date_frist=date_frist.content.decode('gbk') date_frist_=etree.HTML(date_frist) url_down=url_root+str(date_frist_.xpath('//div[@]/a/img/@src')[0]) name=str(date_frist_.xpath('//div[@]/a/img/@title')[0]) path=r'C:\Users\a3139\Desktop\projects\爬蟲dome\pictures'+'\\'+name+'.jpg' print(path) print(url_down) try: request.urlretrieve(url_down,path) request.urlcleanup() except: print('此圖片下載失敗') if url_frist_save.empty(): print(url_frist_save.empty()) break for i in range(5): t1=threading.Thread(target=get_url) t2=threading.Thread(target=down_load) t1.start() t2.start()
這里要注意的是我在這里為這個爬蟲開了五個執行緒,但是這個并不意味著使用Queue可將100個網頁爬取分成每個執行緒爬取20個,同樣他們還是爬取100個每個執行緒,區別是以前是甲先做完再乙去做,現在是甲乙同時做為一組即一個執行緒,除非你給他們分配任務,我之所以這寫主要是為了保證我可以爬取的圖片不會遺漏,這個執行緒沒有爬到這張圖片,但是不代表另一個爬取不到,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/180401.html
標籤:Python
上一篇:Django筆記:檔案上傳
下一篇:go語言安裝快速入門
