Python 线程创建和传参 - Python零基础入门教程
目錄
- 一.Python 線程解釋
- 二.Python 線程創(chuàng)建和啟動(dòng) - 1.導(dǎo)入線程模塊
- 2.創(chuàng)建線程并初始化線程
- 3.啟動(dòng)線程
 
- 三.Python 線程傳參
- 四.Python 線程結(jié)束
- 五.Python 線程相關(guān)函數(shù)介紹
- 六.Python 線程重點(diǎn)總結(jié)
- 七.猜你喜歡
零基礎(chǔ) Python 學(xué)習(xí)路線推薦 : Python 學(xué)習(xí)目錄 >> Python 基礎(chǔ)入門
在以前的文章中雖然我們沒(méi)有介紹過(guò)線程這個(gè)概念,但是實(shí)際上前面所有代碼都是線程,只不過(guò)是單線程,代碼由上而下依次執(zhí)行或者進(jìn)入 main 函數(shù)執(zhí)行,這樣的單線程也稱為主線程。
?
有了單線程的話,什么又是多線程?可以這么理解:一個(gè)線程執(zhí)行一個(gè)代碼塊,多個(gè)線程可以同時(shí)執(zhí)行多個(gè)代碼,使用多線程能讓程序效率更高。舉個(gè)例子,你今天有兩件事需要完成,分別是洗衣服和打掃房間,分別來(lái)看看單線程和多線程如何完成:
單線程:先用洗衣機(jī)洗衣服30分鐘,等衣服洗完之后再打掃房間60分鐘,累計(jì)總耗時(shí):90分鐘;多線程:把衣服放到洗衣機(jī)并且30分鐘后自動(dòng)結(jié)束,然后立刻開(kāi)始打掃房間60分鐘,累計(jì)耗時(shí):60分鐘;由此可見(jiàn),完成同樣的事情,單線程是一件事情做完之后繼續(xù)下一件事情,而多線程可以同時(shí)執(zhí)行多件事情,所以多線程比單線程效率更高!
?
一.Python 線程解釋
線程是 cpu 最小調(diào)度單位,一個(gè)程序中至少有一個(gè)或者多個(gè)線程(至于進(jìn)程暫時(shí)不做講解,后面文章會(huì)有詳細(xì)解釋)!在開(kāi)發(fā)中使用線程可以讓程序運(yùn)行效率更高,多線程類似于同時(shí)執(zhí)行多個(gè)不同代碼塊。
二.Python 線程創(chuàng)建和啟動(dòng)
1.導(dǎo)入線程模塊
# 導(dǎo)入線程threading模塊 import threading2.創(chuàng)建線程并初始化線程
調(diào)用 threading 模塊中的缺省函數(shù) Thread ,創(chuàng)建并初始化線程,返回線程句柄。如果對(duì)缺省函數(shù)已經(jīng)忘記的小伙伴請(qǐng)回到 Python 函數(shù)的聲明和定義中關(guān)于缺省參數(shù)部分復(fù)習(xí)一下。
# 創(chuàng)建并初始化線程,返回線程句柄 t = threading.Thread(target=函數(shù)名)3.啟動(dòng)線程
通過(guò)初始化返回的線程句柄調(diào)用 start 函數(shù),啟動(dòng)線程,此時(shí)會(huì)自動(dòng)執(zhí)行在創(chuàng)建線程時(shí) target 對(duì)應(yīng)的函數(shù)內(nèi)部的代碼:
# 啟動(dòng)線程 t.start()綜合上面三步,下面使用代碼對(duì) Python 線程 thread 做詳細(xì)講解:
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:猿說(shuō)編程 @Blog(個(gè)人博客地址): www.codersrc.com @File:Python 線程創(chuàng)建和傳參.py @Time:2021/04/24 08:00 @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累!"""# 導(dǎo)入線程threading模塊 import threading # 導(dǎo)入內(nèi)置模塊time import timedef wash_clothes():print("洗衣服開(kāi)始...")# sleep 5 秒,默認(rèn)以秒為單位time.sleep(5)print("洗衣服完成...")def clean_room():print("打掃房間開(kāi)始...")# sleep 5 秒,默認(rèn)以秒為單位time.sleep(5)print("打掃房間完成...")if __name__ == "__main__":# 創(chuàng)建線程并初始化 -- 該線程執(zhí)行wash_clothes中的代碼t1 = threading.Thread(target=wash_clothes)# 創(chuàng)建線程并初始化 -- 該線程執(zhí)行clean_room中的代碼t2 = threading.Thread(target=clean_room)t1.start()t2.start()''' 輸出結(jié)果:洗衣服開(kāi)始... 打掃房間開(kāi)始... 洗衣服完成... 打掃房間完成... '''運(yùn)行程序可以發(fā)現(xiàn)程序從運(yùn)行開(kāi)始到結(jié)束,一共耗時(shí) 5 秒時(shí)間!注意觀察輸出日志:
- 第一步:洗衣服開(kāi)始和打掃房間開(kāi)始幾乎同時(shí)開(kāi)始,兩個(gè)事件同時(shí)執(zhí)行.
- 第二步:程序停止 5 秒;
- 第三步:洗衣服和打掃房間幾乎同時(shí)完成
當(dāng)然你也可以按照以前的學(xué)習(xí)的內(nèi)容,先調(diào)用 wash_clothes 函數(shù),在調(diào)用 clean_room 函數(shù),同樣能輸出內(nèi)容,而耗時(shí)卻是 10 秒左右,示例代碼如下:
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:猿說(shuō)編程 @Blog(個(gè)人博客地址): www.codersrc.com @File:Python 線程創(chuàng)建和傳參.py @Time:2021/04/24 08:00 @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累!"""# 導(dǎo)入內(nèi)置模塊time import timedef wash_clothes():print("洗衣服開(kāi)始...")# sleep 5 秒,默認(rèn)以秒為單位time.sleep(5)print("洗衣服完成...")def clean_room():print("打掃房間開(kāi)始...")# sleep 5 秒,默認(rèn)以秒為單位time.sleep(5)print("打掃房間完成...")if __name__ == "__main__":wash_clothes()clean_room()''' 輸出結(jié)果:洗衣服開(kāi)始... 洗衣服完成... 打掃房間開(kāi)始... 打掃房間完成...'''運(yùn)行程序可以發(fā)現(xiàn)程序從運(yùn)行開(kāi)始到結(jié)束,一共耗時(shí) 10 秒時(shí)間!注意觀察輸出日志:
- 第一步:洗衣服開(kāi)始;
- 第二步:程序停止了 5 秒;
- 第三步:洗衣服完成,打掃房間開(kāi)始
- 第四步:程序停止 5 秒;
- 第五步:打掃房間結(jié)束,程序結(jié)束;
由此可見(jiàn):多線程可以同時(shí)運(yùn)行多個(gè)任務(wù),效率遠(yuǎn)比單線程更高!
三.Python 線程傳參
在上面的例子中,我們并沒(méi)有為線程傳遞參數(shù),如果在線程中需要傳遞參數(shù)怎么辦呢?
threading.Thread 函數(shù)中有兩個(gè)缺省參數(shù) args 和 kwargs ,args 是元組類型,kwargs 是字典類型,缺省值默認(rèn)為空,除此之外,其實(shí)還可以設(shè)置線程的名字等,其函數(shù)聲明如下:
(ps:如果對(duì)缺省函數(shù)已經(jīng)忘記的小伙伴請(qǐng)回到 Python 函數(shù)的聲明和定義中關(guān)于缺省參數(shù)部分復(fù)習(xí)一下)
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:猿說(shuō)編程 @Blog(個(gè)人博客地址): www.codersrc.com @File:Python 線程創(chuàng)建和傳參.py @Time:2021/04/24 08:00 @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累!"""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 ThreadGroupclass 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 ofthe 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 targetinvocation. Defaults to {}.If a subclass overrides the constructor, it must make sure to invokethe base class constructor (Thread.__init__()) before doing anythingelse to the thread."""示例代碼如下:
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:猿說(shuō)編程 @Blog(個(gè)人博客地址): www.codersrc.com @File:Python 線程創(chuàng)建和傳參.py @Time:2021/04/24 08:00 @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累!"""# 導(dǎo)入線程threading模塊 import threading # 導(dǎo)入內(nèi)置模塊time import timedef 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 傳遞元組,可以同時(shí)傳遞多個(gè)數(shù)據(jù)# kwargs 傳遞字典,可以同時(shí)傳遞多個(gè)鍵值對(duì)t1 = threading.Thread(target=wash_clothes,args=(1,"猿說(shuō)python"),kwargs={"a":1,"b":False}) # args 傳遞元組,可以同時(shí)傳遞多個(gè)數(shù)據(jù)# kwargs 傳遞字典,可以同時(shí)傳遞多個(gè)鍵值對(duì)t2 = threading.Thread(target=clean_room,args=(2,False),kwargs={"c":0.2,"d":False})t1.start()t2.start()四.Python 線程結(jié)束
值得思考的是:在上面這份代碼中一共有幾個(gè)線程呢?并非兩個(gè),一共是三個(gè)線程:
- 線程一:__name__ == “__main__” 作為主線程;
- 線程二:t1 作為子線程;
- 線程三:t2 作為子線程;
注意:主程序會(huì)等待所有子程序結(jié)束之后才會(huì)結(jié)束!
五.Python 線程相關(guān)函數(shù)介紹
- 1.threading.Thread — 創(chuàng)建線程并初始化線程,可以為線程傳遞參數(shù) ;
- 2.threading.enumerate — 返回一個(gè)包含正在運(yùn)行的線程的 list;
- 3.threading.activeCount — 返回正在運(yùn)行的線程數(shù)量,與 len(threading.enumerate)有相同的結(jié)果;
- 4.Thread.start — 啟動(dòng)線程 ;
- 5.Thread.join — 阻塞函數(shù),一直等到線程結(jié)束為止 ;
- 6.Thread.isAlive — 返回線程是否活動(dòng)的;
- 7.Thread.getName — 返回線程名;
- 8.Thread.setName — 設(shè)置線程名;
- 9.Thread.setDaemon — 設(shè)置為后臺(tái)線程,這里默認(rèn)是 False,設(shè)置為 True 之后則主線程不會(huì)再等待子線程結(jié)束才結(jié)束,而是主線程結(jié)束意味程序退出,子線程也立即結(jié)束,注意調(diào)用時(shí)必須設(shè)置在 start 之前;
簡(jiǎn)單的示例代碼:
# !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:猿說(shuō)編程 @Blog(個(gè)人博客地址): www.codersrc.com @File:Python 線程創(chuàng)建和傳參.py @Time:2021/04/24 08:00 @Motto:不積跬步無(wú)以至千里,不積小流無(wú)以成江海,程序人生的精彩需要堅(jiān)持不懈地積累!"""# 導(dǎo)入線程threading模塊 import threading # 導(dǎo)入內(nèi)置模塊time import timedef 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 傳遞元組,可以同時(shí)傳遞多個(gè)數(shù)據(jù)# kwargs 傳遞字典,可以同時(shí)傳遞多個(gè)鍵值對(duì)t1 = threading.Thread(target=wash_clothes,args=(1,"猿說(shuō)python"),kwargs={"a":1,"b":False})t2 = threading.Thread(target=clean_room,args=(2,False),kwargs={"c":0.2,"d":False})# setDaemon(True)意味著主線程退出,不管子線程執(zhí)行到哪一步,子線程自動(dòng)結(jié)束# 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())''' 輸出結(jié)果: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, '猿說(shuō)python') wash_clothes: {'a': 1, 'b': False} clean_room: {'c': 0.2, 'd': False}'''六.Python 線程重點(diǎn)總結(jié)
1.默認(rèn)主線程會(huì)等待所有子線程結(jié)束之后才會(huì)結(jié)束,主線程結(jié)束意味著程序退出;如果 setDaemon 設(shè)置為 True ,主線程則不會(huì)等待子線程,主線程結(jié)束,子線程自動(dòng)結(jié)束;
2.threading 模塊除了以上常用函數(shù),還有互斥鎖 Lock / 事件 Event / 信號(hào)量 Condition / 隊(duì)列 Queue 等,由于篇幅有限,后面文章再一一講解!!
七.猜你喜歡
未經(jīng)允許不得轉(zhuǎn)載:猿說(shuō)編程 ? Python 線程創(chuàng)建和傳參
總結(jié)
以上是生活随笔為你收集整理的Python 线程创建和传参 - Python零基础入门教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Python random 模块 - P
- 下一篇: Python 字符串/列表/元组/字典之
