<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
幾乎所有的作業系統都支援同時執行多個任務,每個任務通常是一個程式,每一個執行中的程式就是一個程序,即程序是應用程式的執行範例。現代的作業系統幾乎都支援多程序並行執行。注意,並行和並行是兩個概念,並行指在同一時刻有多條指令在多個處理器上同時執行;並行是指在同一時刻只能有一條指令執行,但多個程序指令被快速輪換執行,使得在宏觀上具有多個程序同時執行的效果。
例如,程式設計師一邊開著開發工具在寫程式,一邊開著參考手冊備查,同時還使用電腦播放音樂……除此之外,每臺電腦執行時還有大量底層的支撐性程式在執行……這些程序看上去像是在同時工作。但事實的真相是,對於一個 CPU 而言,在某個時間點它只能執行一個程式。也就是說,只能執行一個程序,CPU 不斷地在這些程序之間輪換執行。那麼,為什麼使用者感覺不到任何中斷呢?這是因為相對人的感覺來說,CPU 的執行速度太快了(如果啟動的程式足夠多,則使用者依然可以感覺到程式的執行速度下降了)。所以,雖然 CPU 在多個程序之間輪換執行,但使用者感覺到好像有多個程序在同時執行。
執行緒是程序的組成部分,一個程序可以擁有多個執行緒。在多執行緒中,會有一個主執行緒來完成整個程序從開始到結束的全部操作,而其他的執行緒會在主執行緒的執行過程中被建立或退出。當程序被初始化後,主執行緒就被建立了,對於絕大多數的應用程式來說,通常僅要求有一個主執行緒,但也可以在程序內建立多個順序執行流,這些順序執行流就是執行緒。當一個程序裡只有一個執行緒時,叫作單執行緒。超過一個執行緒就叫作多執行緒。每個執行緒必須有自己的父程序,且它可以擁有自己的堆疊、程式計數器和區域性變數,但不擁有系統資源,因為它和父程序的其他執行緒共用該程序所擁有的全部資源。執行緒可以完成一定的任務,可以與其他執行緒共用父程序中的共用變數及部分環境,相互之間協同完成程序所要完成的任務。多個執行緒共用父程序裡的全部資源,會使得程式設計更加方便,需要注意的是,要確保執行緒不會妨礙同一程序中的其他執行緒。執行緒是獨立執行的,它並不知道程序中是否還有其他執行緒存在。執行緒的執行是搶佔式的,也就是說,當前執行的執行緒在任何時候都可能被掛起,以便另外一個執行緒可以執行。多執行緒也是並行執行的,即同一時刻,Python 主程式只允許有一個執行緒執行,這和全域性直譯器鎖有關係,後續會做詳細介紹。
一個執行緒可以建立和復原另一個執行緒,同一個程序中的多個執行緒之間可以並行執行。從邏輯的角度來看,多執行緒存在於一個應用程式中,讓一個應用程式可以有多個執行部分同時執行,但作業系統無須將多個執行緒看作多個獨立的應用,對多執行緒實現排程和管理以及資源分配,執行緒的排程和管理由程序本身負責完成。
簡而言之,程序和執行緒的關係是這樣的:作業系統可以同時執行多個任務,每一個任務就是一個程序,程序可以同時執行多個任務,每一個任務就是一個執行緒。
Python 中,有關執行緒開發的部分被單獨封裝到了模組中,和執行緒相關的模組有以下 2 個:
_thread
:是 Python 3 以前版本中 thread 模組的重新命名,此模組僅提供了低階別的、原始的執行緒支援,以及一個簡單的鎖。功能比較有限。正如它的名字所暗示的(以 _ 開頭),一般不建議使用 thread 模組;
threading
:Python 3 之後的執行緒模組,提供了功能豐富的多執行緒支援,推薦使用。
本節就以 threading 模組為例進行講解。Python 主要通過兩種方式來建立執行緒:
Thread 類提供瞭如下的 __init__()
構造器,可以用來建立執行緒:__init__(self, group=None, target=None, name=None, args=(), kwargs=None, *,daemon=None)
此構造方法中,以上所有引數都是可選引數,即可以使用,也可以忽略。其中各個引數的含義如下:
下面程式演示瞭如何使用 Thread 類的構造方法建立一個執行緒:
import threading #定義執行緒要呼叫的方法,*add可接收多個以非關鍵字方式傳入的引數 def action(*add): for arc in add: #呼叫 getName() 方法獲取當前執行該程式的執行緒名 print(threading.current_thread().getName() +" "+ arc) #定義為執行緒方法傳入的引數 my_tuple = ("http://c.biancheng.net/python/", "http://c.biancheng.net/shell/", "http://c.biancheng.net/java/") #建立執行緒 thread = threading.Thread(target = action,args =my_tuple)
有關 Thread 類提供的和執行緒有關的方法,可閱讀 Python Thread手冊,由於不是本節重點,這裡不再進行詳細介紹。
由此就建立好了一個執行緒。但是執行緒需要手動啟動才能執行,threading 模組提供了 start() 方法用來啟動執行緒。因此在上面程式的基礎上,新增如下語句:thread.start()
再次執行程式,
其輸出結果為:
Thread-1 http://c.biancheng.net/python/
Thread-1 http://c.biancheng.net/shell/
Thread-1 http://c.biancheng.net/java/
可以看到,新建立的 thread 執行緒(執行緒名為 Thread-1)執行了 action() 函數。
預設情況下,主執行緒的名字為 MainThread,使用者啟動的多個執行緒的名字依次為 Thread-1、Thread-2、Thread-3、…、Thread-n 等。
為了使 thread 執行緒的作用更加明顯,可以繼續在上面程式的基礎上新增如下程式碼,讓主執行緒和新建立執行緒同時工作:
for i in range(5): print(threading.current_thread().getName())
再次執行程式,其輸出結果為:
MainThreadThread-1 http://c.biancheng.net/python/
MainThreadThread-1 http://c.biancheng.net/shell/
MainThreadThread-1 http://c.biancheng.net/java/
MainThread
MainThread
可以看到,當前程式中有 2 個執行緒,分別為主執行緒 MainThread 和子執行緒 Thread-1,它們以並行方式執行,即 Thread-1 執行一段時間,然後 MainThread 執行一段時間。通過輪流獲得 CPU 執行一段時間的方式,程式的執行在多個執行緒之間切換,從而給使用者一種錯覺,即多個執行緒似乎同時在執行。
如果程式中不顯式建立任何執行緒,則所有程式的執行,都將由主執行緒 MainThread 完成,程式就只能按照順序依次執行。
通過繼承 Thread 類,我們可以自定義一個執行緒類,從而範例化該類物件,獲得子執行緒。需要注意的是,在建立 Thread 類的子類時,必須重寫從父類別繼承得到的 run() 方法。因為該方法即為要建立的子執行緒執行的方法,其功能如同第一種建立方法中的 action() 自定義函數。
下面程式,演示瞭如何通過繼承 Thread 類建立並啟動一個執行緒:
import threading #建立子執行緒類,繼承自 Thread 類 class my_Thread(threading.Thread): def __init__(self,add): threading.Thread.__init__(self) self.add = add # 重寫run()方法 def run(self): for arc in self.add: #呼叫 getName() 方法獲取當前執行該程式的執行緒名 print(threading.current_thread().getName() +" "+ arc) #定義為 run() 方法傳入的引數 my_tuple = ("http://c.biancheng.net/python/", "http://c.biancheng.net/shell/", "http://c.biancheng.net/java/") #建立子執行緒 mythread = my_Thread(my_tuple) #啟動子執行緒 mythread.start() #主執行緒執行此迴圈 for i in range(5): print(threading.current_thread().getName())
程式執行結果為:
MainThreadThread-1 http://c.biancheng.net/python/
MainThreadThread-1 http://c.biancheng.net/shell/
MainThreadThread-1 http://c.biancheng.net/java/
MainThread
MainThread
此程式中,子執行緒 Thread-1 執行的是 run() 方法中的程式碼,而 MainThread 執行的是主程式中的程式碼,它們以快速輪換 CPU 的方式在執行。
如何通過 Thread 類建立並啟動一個執行緒,當時給讀者用如下的程式進行演示:
import threading #定義執行緒要呼叫的方法,*add可接收多個以非關鍵字方式傳入的引數 def action(*add): for arc in add: #呼叫 getName() 方法獲取當前執行該程式的執行緒名 print(threading.current_thread().getName() +" "+ arc) #定義為執行緒方法傳入的引數 my_tuple = ("http://c.biancheng.net/python/", "http://c.biancheng.net/shell/", "http://c.biancheng.net/java/") #建立執行緒 thread = threading.Thread(target = action,args =my_tuple) #啟動執行緒 thread.start() #主執行緒執行如下語句 for i in range(5): print(threading.current_thread().getName())
程式執行結果為(不唯一):
Thread-1 http://c.biancheng.net/python/MainThread
Thread-1 http://c.biancheng.net/shell/MainThread
Thread-1 http://c.biancheng.net/java/MainThread
MainThread
MainThread
可以看到,我們用 Thread 類建立了一個執行緒(執行緒名為 Thread-1),其任務是執行 action() 函數。同時,我們也給主執行緒 MainThread 安排了迴圈任務(第 16、17 行)。通過前面的學習我們知道,主執行緒 MainThread 和子執行緒 Thread-1 會輪流獲得 CPU 資源,因此該程式的輸出結果才會向上面顯示的這樣。
但是,如果我們想讓 Thread-1 子執行緒先執行,然後再讓 MainThread 執行第 16、17 行程式碼,該如何實現呢?很簡單,通過呼叫執行緒物件的 join() 方法即可。
join() 方法的功能是在程式指定位置,優先讓該方法的呼叫者使用 CPU 資源。該方法的語法格式如下:thread.join( [timeout] )
其中,thread 為 Thread 類或其子類的範例化物件;timeout 引數作為可選引數,其功能是指定 thread 執行緒最多可以霸佔 CPU 資源的時間(以秒為單位),如果省略,則預設直到 thread 執行結束(進入死亡狀態)才釋放 CPU 資源。
舉個例子,修改上面的程式碼,如下所示:
import threading #定義執行緒要呼叫的方法,*add可接收多個以非關鍵字方式傳入的引數 def action(*add): for arc in add: #呼叫 getName() 方法獲取當前執行該程式的執行緒名 print(threading.current_thread().getName() +" "+ arc) #定義為執行緒方法傳入的引數 my_tuple = ("http://c.biancheng.net/python/", "http://c.biancheng.net/shell/", "http://c.biancheng.net/java/") #建立執行緒 thread = threading.Thread(target = action,args =my_tuple) #啟動執行緒 thread.start() #指定 thread 執行緒優先執行完畢 thread.join() #主執行緒執行如下語句 for i in range(5): print(threading.current_thread().getName())
程式執行結果為:
Thread-1 http://c.biancheng.net/python/
Thread-1 http://c.biancheng.net/shell/
Thread-1 http://c.biancheng.net/java/
MainThread
MainThread
MainThread
MainThread
MainThread
程式中第 16 行的位置,thread 執行緒呼叫了 join() 方法,並且沒有指定具體的 timeout 引數值。這意味著如果程式想繼續往下執行,必須先執行完 thread 執行緒。
到此這篇關於Python執行緒threading(Thread類)的文章就介紹到這了,更多相關Python執行緒 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45