目錄
- 一.Python 執行緒解釋
- 二.Python 執行緒創建和啟動
- 1.匯入執行緒模塊
- 2.創建執行緒并初始化執行緒
- 3.啟動執行緒
- 三.Python 執行緒傳參
- 四.Python 執行緒結束
- 五.Python 執行緒相關函式介紹
- 六.Python 執行緒重點總結
- 七.猜你喜歡
零基礎 Python 學習路線推薦 : Python 學習目錄 >> Python 基礎入門
在以前的文章中雖然我們沒有介紹過執行緒這個概念,但是實際上前面所有代碼都是執行緒,只不過是單執行緒,代碼由上而下依次執行或者進入 main 函式執行,這樣的單執行緒也稱為主執行緒,
?
有了單執行緒的話,什么又是多執行緒?可以這么理解:一個執行緒執行一個代碼塊,多個執行緒可以同時執行多個代碼,使用多執行緒能讓程式效率更高,舉個例子,你今天有兩件事需要完成,分別是洗衣服和打掃房間,分別來看看單執行緒和多執行緒如何完成:
單執行緒:先用洗衣機洗衣服30分鐘,等衣服洗完之后再打掃房間60分鐘,累計總耗時:90分鐘;
多執行緒:把衣服放到洗衣機并且30分鐘后自動結束,然后立刻開始打掃房間60分鐘,累計耗時:60分鐘;
由此可見,完成同樣的事情,單執行緒是一件事情做完之后繼續下一件事情,而多執行緒可以同時執行多件事情,所以多執行緒比單執行緒效率更高!
?
一.Python 執行緒解釋
執行緒是 cpu 最小調度單位,一個程式中至少有一個或者多個執行緒(至于行程暫時不做講解,后面文章會有詳細解釋)!在開發中使用執行緒可以讓程式運行效率更高,多執行緒類似于同時執行多個不同代碼塊,
二.Python 執行緒創建和啟動
1.匯入執行緒模塊
# 匯入執行緒threading模塊
import threading
2.創建執行緒并初始化執行緒
呼叫 threading 模塊中的預設函式 Thread ,創建并初始化執行緒,回傳執行緒句柄,如果對預設函式已經忘記的小伙伴請回到 Python 函式的宣告和定義中關于預設引數部分復習一下,
# 創建并初始化執行緒,回傳執行緒句柄
t = threading.Thread(target=函式名)
3.啟動執行緒
通過初始化回傳的執行緒句柄呼叫 start 函式,啟動執行緒,此時會自動執行在創建執行緒時 target 對應的函式內部的代碼:
# 啟動執行緒
t.start()
綜合上面三步,下面使用代碼對 Python 執行緒 thread 做詳細講解:
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:猿說編程
@Blog(個人博客地址): www.codersrc.com
@File:Python 執行緒創建和傳參.py
@Time:2021/04/24 08:00
@Motto:不積跬步無以至千里,不積小流無以成江海,程式人生的精彩需要堅持不懈地積累!
"""
# 匯入執行緒threading模塊
import threading
# 匯入內置模塊time
import time
def wash_clothes():
print("洗衣服開始...")
# sleep 5 秒,默認以秒為單位
time.sleep(5)
print("洗衣服完成...")
def clean_room():
print("打掃房間開始...")
# sleep 5 秒,默認以秒為單位
time.sleep(5)
print("打掃房間完成...")
if __name__ == "__main__":
# 創建執行緒并初始化 -- 該執行緒執行wash_clothes中的代碼
t1 = threading.Thread(target=wash_clothes)
# 創建執行緒并初始化 -- 該執行緒執行clean_room中的代碼
t2 = threading.Thread(target=clean_room)
t1.start()
t2.start()
'''
輸出結果:
洗衣服開始...
打掃房間開始...
洗衣服完成...
打掃房間完成...
'''
運行程式可以發現程式從運行開始到結束,一共耗時 5 秒時間!注意觀察輸出日志:
- 第一步:洗衣服開始和打掃房間開始幾乎同時開始,兩個事件同時執行.
- 第二步:程式停止 5 秒;
- 第三步:洗衣服和打掃房間幾乎同時完成
當然你也可以按照以前的學習的內容,先呼叫 wash_clothes 函式,在呼叫 clean_room 函式,同樣能輸出內容,而耗時卻是 10 秒左右,示例代碼如下:
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:猿說編程
@Blog(個人博客地址): www.codersrc.com
@File:Python 執行緒創建和傳參.py
@Time:2021/04/24 08:00
@Motto:不積跬步無以至千里,不積小流無以成江海,程式人生的精彩需要堅持不懈地積累!
"""
# 匯入內置模塊time
import time
def wash_clothes():
print("洗衣服開始...")
# sleep 5 秒,默認以秒為單位
time.sleep(5)
print("洗衣服完成...")
def clean_room():
print("打掃房間開始...")
# sleep 5 秒,默認以秒為單位
time.sleep(5)
print("打掃房間完成...")
if __name__ == "__main__":
wash_clothes()
clean_room()
'''
輸出結果:
洗衣服開始...
洗衣服完成...
打掃房間開始...
打掃房間完成...
'''
運行程式可以發現程式從運行開始到結束,一共耗時 10 秒時間!注意觀察輸出日志:
- 第一步:洗衣服開始;
- 第二步:程式停止了 5 秒;
- 第三步:洗衣服完成,打掃房間開始
- 第四步:程式停止 5 秒;
- 第五步:打掃房間結束,程式結束;
由此可見:多執行緒可以同時運行多個任務,效率遠比單執行緒更高!
三.Python 執行緒傳參
在上面的例子中,我們并沒有為執行緒傳遞引數,如果在執行緒中需要傳遞引數怎么辦呢?
threading.Thread 函式中有兩個預設引數 args 和 kwargs ,args 是元組型別,kwargs 是字典型別,預設值默認為空,除此之外,其實還可以設定執行緒的名字等,其函式宣告如下:
(ps:如果對預設函式已經忘記的小伙伴請回到 Python 函式的宣告和定義中關于預設引數部分復習一下)
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:猿說編程
@Blog(個人博客地址): www.codersrc.com
@File:Python 執行緒創建和傳參.py
@Time:2021/04/24 08:00
@Motto:不積跬步無以至千里,不積小流無以成江海,程式人生的精彩需要堅持不懈地積累!
"""
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, *, daemon=None):
"""This constructor should always be called with keyword arguments. Arguments are:
*group* should be None; reserved for future extension when a ThreadGroup
class is implemented.
*target* is the callable object to be invoked by the run()
method. Defaults to None, meaning nothing is called.
*name* is the thread name. By default, a unique name is constructed of
the form "Thread-N" where N is a small decimal number.
*args* is the argument tuple for the target invocation. Defaults to ().
*kwargs* is a dictionary of keyword arguments for the target
invocation. Defaults to {}.
If a subclass overrides the constructor, it must make sure to invoke
the base class constructor (Thread.__init__()) before doing anything
else to the thread.
"""
示例代碼如下:
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:猿說編程
@Blog(個人博客地址): www.codersrc.com
@File:Python 執行緒創建和傳參.py
@Time:2021/04/24 08:00
@Motto:不積跬步無以至千里,不積小流無以成江海,程式人生的精彩需要堅持不懈地積累!
"""
# 匯入執行緒threading模塊
import threading
# 匯入內置模塊time
import time
def wash_clothes(*args,**kargcs):
print("wash_clothes:",args)
print("wash_clothes:", kargcs)
def clean_room(*args,**kargcs):
print("clean_room:",args)
print("clean_room:", kargcs)
if __name__ == "__main__":
# args 傳遞元組,可以同時傳遞多個資料
# kwargs 傳遞字典,可以同時傳遞多個鍵值對
t1 = threading.Thread(target=wash_clothes,args=(1,"猿說python"),kwargs={"a":1,"b":False})
# args 傳遞元組,可以同時傳遞多個資料
# kwargs 傳遞字典,可以同時傳遞多個鍵值對
t2 = threading.Thread(target=clean_room,args=(2,False),kwargs={"c":0.2,"d":False})
t1.start()
t2.start()
四.Python 執行緒結束
值得思考的是:在上面這份代碼中一共有幾個執行緒呢?并非兩個,一共是三個執行緒:
- 執行緒一:__name__ == “__main__” 作為主執行緒;
- 執行緒二:t1 作為子執行緒;
- 執行緒三:t2 作為子執行緒;
注意:主程式會等待所有子程式結束之后才會結束!
五.Python 執行緒相關函式介紹
- 1.threading.Thread — 創建執行緒并初始化執行緒,可以為執行緒傳遞引數 ;
- 2.threading.enumerate — 回傳一個包含正在運行的執行緒的 list;
- 3.threading.activeCount — 回傳正在運行的執行緒數量,與 len(threading.enumerate)有相同的結果;
- 4.Thread.start — 啟動執行緒 ;
- 5.Thread.join — 阻塞函式,一直等到執行緒結束為止 ;
- 6.Thread.isAlive — 回傳執行緒是否活動的;
- 7.Thread.getName — 回傳執行緒名;
- 8.Thread.setName — 設定執行緒名;
- 9.Thread.setDaemon — 設定為后臺執行緒,這里默認是 False,設定為 True 之后則主執行緒不會再等待子執行緒結束才結束,而是主執行緒結束意味程式退出,子執行緒也立即結束,注意呼叫時必須設定在 start 之前;
簡單的示例代碼:
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:猿說編程
@Blog(個人博客地址): www.codersrc.com
@File:Python 執行緒創建和傳參.py
@Time:2021/04/24 08:00
@Motto:不積跬步無以至千里,不積小流無以成江海,程式人生的精彩需要堅持不懈地積累!
"""
# 匯入執行緒threading模塊
import threading
# 匯入內置模塊time
import time
def wash_clothes(*args,**kargcs):
time.sleep(2)
print("wash_clothes:",args)
time.sleep(2)
print("wash_clothes:", kargcs)
def clean_room(*args,**kargcs):
time.sleep(2)
print("clean_room:",args)
time.sleep(2)
print("clean_room:", kargcs)
if __name__ == "__main__":
# args 傳遞元組,可以同時傳遞多個資料
# kwargs 傳遞字典,可以同時傳遞多個鍵值對
t1 = threading.Thread(target=wash_clothes,args=(1,"猿說python"),kwargs={"a":1,"b":False})
t2 = threading.Thread(target=clean_room,args=(2,False),kwargs={"c":0.2,"d":False})
# setDaemon(True)意味著主執行緒退出,不管子執行緒執行到哪一步,子執行緒自動結束
# t1.setDaemon(True)
# t2.setDaemon(True)
t1.start()
t2.start()
print("threading.enumerate():",threading.enumerate())
print("threading.activeCount():", threading.activeCount())
print("t1.isAlive():",t1.isAlive())
print("t1.getName():", t1.getName())
print("t2.isAlive():", t2.isAlive())
t2.setName("my_custom_thread_2")
print("t2.getName():", t2.getName())
'''
輸出結果:
threading.enumerate(): [<_MainThread(MainThread, started 18388)>, <Thread(Thread-1, started 16740)>, <Thread(Thread-2, started 17888)>]
threading.activeCount(): 3
t1.isAlive(): True
t1.getName(): Thread-1
t2.isAlive(): True
t2.getName(): my_custom_thread_2
clean_room: (2, False)
wash_clothes: (1, '猿說python')
wash_clothes: {'a': 1, 'b': False}
clean_room: {'c': 0.2, 'd': False}
'''
六.Python 執行緒重點總結
1.默認主執行緒會等待所有子執行緒結束之后才會結束,主執行緒結束意味著程式退出;如果 setDaemon 設定為 True ,主執行緒則不會等待子執行緒,主執行緒結束,子執行緒自動結束;
2.threading 模塊除了以上常用函式,還有互斥鎖 Lock / 事件 Event / 信號量 Condition / 佇列 Queue 等,由于篇幅有限,后面文章再一一講解!!
七.猜你喜歡
- Python for 回圈
- Python 字串
- Python 串列 list
- Python 元組 tuple
- Python 字典 dict
- Python 條件推導式
- Python 串列推導式
- Python 字典推導式
- Python 函式宣告和呼叫
- Python 不定長引數 *argc/**kargcs
- Python 匿名函式 lambda
- Python return 邏輯判斷運算式
- Python 字串/串列/元組/字典之間的相互轉換
- Python 區域變數和全域變數
- Python type 函式和 isinstance 函式區別
- Python is 和 == 區別
- Python 可變資料型別和不可變資料型別
- Python 淺拷貝和深拷貝
未經允許不得轉載:猿說編程 ? Python 執行緒創建和傳參
本文由博客 - 猿說編程 猿說編程 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/288307.html
標籤:其他
