本文目錄一覽:
python如何實現線程池
#這個類是線程類,用來在主程序中調用生成一個線程。其實線程池就是線程的集合地,
#能夠解決有效統一的管理線程,基本就達到了線程池的目的;
#這一段代碼是我的爬蟲程序中的一部分,希望對你有用。
class Spider(Thread):
def __init__(self, todo_list):
super().__init__()
self.setDaemon(True)
self.todo_list = todo_list
self.stat = IDLE
def is_idle(self):
return self.stat == IDLE
def run(self):
while True:
url = self.todo_list.get()
# 開始線程工作
#這個函數就是主函數了,
def main(max_threads):
########這裡和上一個函數就是核心代碼了。
# 創建 N 個線程,並啟動
print(‘Spawn spiders’)
spiders = [Spider(todo_list) for i in range(max_threads)]
for spd in spiders:
spd.start()
#python主運行代碼:
if __name__ == ‘__main__’:
main(max_threads)
只能給你這麼多解釋了,如果想弄懂,還是要去看看基礎知識的。
另外可以查一下有沒有封裝好的三方庫。
python的多線程使用setDaemon有什麼意義
因為python的全局解釋器鎖的機制, 導致python的多線程並不是真正的多線程, 效率上不僅不會比單線程快,反而可能更慢, 所以說是雞肋,要求速度好話,可以用多進程來實現
Python中threading的join和setDaemon的區別及用法
Python多線程編程時經常會用到join()和setDaemon()方法,基本用法如下:
join([time]): 等待至線程中止。這阻塞調用線程直至線程的join() 方法被調用中止-正常退出或者拋出未處理的異常-或者是可選的超時發生。
setDaemon,將該線程標記為守護線程或用戶線程
1、join ()方法:主線程A中,創建了子線程B,並且在主線程A中調用了B.join(),那麼,主線程A會在調用的地方等待,直到子線程B完成操作後,才可以接着往下執行,那麼在調用這個線程時可以使用被調用線程的join方法。
原型:join([timeout]),裡面的參數時可選的,代表線程運行的最大時間,即如果超過這個時間,不管這個此線程有沒有執行完畢都會被回收,然後主線程或函數都會接着執行的。
import threadingimport time class MyThread(threading.Thread): def __init__(self, id): threading.Thread.__init__(self) self.id = id def run(self): x = 0 time.sleep(10) print(self.id) print(‘線程結束:’+str(time.time())) if __name__ == “__main__”: t1 = MyThread(999) print(‘線程開始:’+str(time.time())) t1.start() print(‘主線程打印開始:’+str(time.time())) for i in range(5): print(i) time.sleep(2) print(‘主線程打印結束:’ + str(time.time()))
線程開始:1497534590.2784667
主線程打印開始:1497534590.2794669
1
2
3
4
主線程打印結束:1497534592.279581
999
線程結束:1497534600.2800388
從打印結果可知,線程t1 start後,主線程並沒有等線程t1運行結束後再執行,而是在線程執行的同時,執行了後面的語句。
現在,把join()方法加到啟動線程後面(其他代碼不變)
import threadingimport time class MyThread(threading.Thread): def __init__(self, id): threading.Thread.__init__(self) self.id = id def run(self): x = 0 time.sleep(10) print(self.id) print(‘線程結束:’+str(time.time())) if __name__ == “__main__”: t1 = MyThread(999) print(‘線程開始:’+str(time.time())) t1.start() t1.join() print(‘主線程打印開始:’+str(time.time())) for i in range(5): print(i) time.sleep(2) print(‘主線程打印結束:’ + str(time.time()))
線程開始:1497535176.5019968
999
線程結束:1497535186.5025687
主線程打印開始:1497535186.5025687
1
2
3
4
主線程打印結束:1497535188.5026832
線程t1 start後,主線程停在了join()方法處,等子線程t1結束後,主線程繼續執行join後面的語句。
2、setDaemon()方法。主線程A中,創建了子線程B,並且在主線程A中調用了B.setDaemon(),這個的意思是,把主線程A設置為守護線程,這時候,要是主線程A執行結束了,就不管子線程B是否完成,一併和主線程A退出.這就是setDaemon方法的含義,這基本和join是相反的。此外,還有個要特別注意的:必須在start() 方法調用之前設置。import threading
import time class MyThread(threading.Thread): def __init__(self, id): threading.Thread.__init__(self) self.id = id def run(self): x = 0 time.sleep(10) print(self.id) print(“This is:” + self.getName()) # 獲取線程名稱 print(‘線程結束:’ + str(time.time())) if __name__ == “__main__”: t1 = MyThread(999) print(‘線程開始:’+str(time.time())) t1.setDaemon(True) t1.start() print(‘主線程打印開始:’+str(time.time())) for i in range(5): print(i) time.sleep(2) print(‘主線程打印結束:’ + str(time.time()))
線程開始:1497536678.8509264
主線程打印開始:1497536678.8509264
1
2
3
4
主線程打印結束:1497536680.8510408
t1.setDaemon(True)的操作,將子線程設置為了守護線程。根據setDaemon()方法的含義,父線程打印內容後便結束了,不管子線程是否執行完畢了。
如果在線程啟動前沒有加t1.setDaemon(True),輸出結果為:
線程開始:1497536865.3215919
主線程打印開始:1497536865.3215919
1
2
3
4
主線程打印結束:1497536867.3217063
999
This is:Thread-1
線程結束:1497536875.3221638
程序運行中,執行一個主線程,如果主線程又創建一個子線程,主線程和子線程就分兵兩路,分別運行,那麼當主線程完成想退出時,會檢驗子線程是否完成,如果子線程未完成,則主線程會等待子線程完成後再退出;
有時我們需要的是,子線程運行完,才繼續運行主線程,這時就可以用join方法(在線程啟動後面);
但是有時候我們需要的是,只要主線程完成了,不管子線程是否完成,都要和主線程一起退出,這時就可以用setDaemon方法(在線程啟動前面)。
python之多線程原理
並發:邏輯上具備同時處理多個任務的能力。
並行:物理上在同一時刻執行多個並發任務。
舉例:開個QQ,開了一個進程,開了微信,開了一個進程。在QQ這個進程裡面,傳輸文字開一個線程、傳輸語音開了一個線程、彈出對話框又開了一個線程。
總結:開一個軟件,相當於開了一個進程。在這個軟件運行的過程里,多個工作同時運轉,完成了QQ的運行,那麼這個多個工作分別有多個線程。
線程和進程之間的區別:
進程在python中的使用,對模塊threading進行操作,調用的這個三方庫。可以通過 help(threading) 了解其中的方法、變量使用情況。也可以使用 dir(threading) 查看目錄結構。
current_thread_num = threading.active_count() # 返回正在運行的線程數量
run_thread_len = len(threading.enumerate()) # 返回正在運行的線程數量
run_thread_list = threading.enumerate() # 返回當前運行線程的列表
t1=threading.Thread(target=dance) #創建兩個子線程,參數傳遞為函數名
t1.setDaemon(True) # 設置守護進程,守護進程:主線程結束時自動退出子線程。
t1.start() # 啟動子線程
t1.join() # 等待進程結束 exit()`# 主線程退出,t1子線程設置了守護進程,會自動退出。其他子線程會繼續執行。
原創文章,作者:KGQL,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/132058.html