
Python中的併發 - 執行緒
一般來說,我們知道線是一種非常細的扭曲的線,通常由棉或絲織物製成,用於縫製衣服等。相同的術語“執行緒”也用於計算機程式設計領域。現在,我們如何將用於縫製衣服的線與用於計算機程式設計的線聯絡起來呢?兩種執行緒執行的角色在這裡是相似的。在衣服中,線將布料固定在一起,而在計算機程式設計中,線將計算機程式固定在一起,並允許程式一次執行順序操作或多個操作。
執行緒是作業系統中最小的執行單元。它本身不是一個程式,而是在程式中執行。換句話說,執行緒彼此不獨立,並且與其他執行緒共享程式碼段、資料段等。這些執行緒也稱為輕量級程序。
執行緒的狀態
為了深入瞭解執行緒的功能,我們需要了解執行緒的生命週期或不同的執行緒狀態。通常,一個執行緒可以存在於五個不同的狀態中。不同的狀態如下所示:
新執行緒
一個新執行緒從新狀態開始其生命週期。但是,在此階段,它尚未啟動,也沒有分配任何資源。我們可以說它只是一個物件的例項。
可執行
當新建立的執行緒啟動時,執行緒變為可執行狀態,即等待執行。在此狀態下,它擁有所有資源,但任務排程程式尚未將其安排執行。
執行
在此狀態下,執行緒取得進展並執行任務,該任務已被任務排程程式選中以執行。現在,執行緒可以進入終止狀態或不可執行/等待狀態。
不可執行/等待
在此狀態下,執行緒被暫停,因為它正在等待某些I/O請求的響應,或者正在等待其他執行緒執行完成。
終止
當可執行執行緒完成其任務或以其他方式終止時,它將進入終止狀態。
下圖顯示了執行緒的完整生命週期:

執行緒的型別
在本節中,我們將看到不同型別的執行緒。型別如下所述:
使用者級執行緒
這些是使用者管理的執行緒。
在這種情況下,執行緒管理核心不知道執行緒的存在。執行緒庫包含用於建立和銷燬執行緒、線上程之間傳遞訊息和資料、排程執行緒執行以及儲存和恢復執行緒上下文的程式碼。應用程式以單個執行緒啟動。
使用者級執行緒的示例包括:
- Java執行緒
- POSIX執行緒

使用者級執行緒的優點
以下是使用者級執行緒的不同優點:
- 執行緒切換不需要核心模式許可權。
- 使用者級執行緒可以在任何作業系統上執行。
- 排程可以在使用者級執行緒中特定於應用程式。
- 使用者級執行緒建立和管理速度快。
使用者級執行緒的缺點
以下是使用者級執行緒的不同缺點:
- 在典型的作業系統中,大多數系統呼叫都是阻塞的。
- 多執行緒應用程式無法利用多處理。
核心級執行緒
作業系統管理的執行緒作用於核心,核心是作業系統的核心。
在這種情況下,核心執行執行緒管理。應用程式區域中沒有執行緒管理程式碼。核心執行緒由作業系統直接支援。任何應用程式都可以程式設計為多執行緒。應用程式中的所有執行緒都支援在一個程序內。
核心維護整個程序以及程序內各個執行緒的上下文資訊。核心的排程以執行緒為基礎進行。核心在核心空間執行執行緒建立、排程和管理。核心執行緒的建立和管理通常比使用者執行緒慢。核心級執行緒的示例包括Windows和Solaris。

核心級執行緒的優點
以下是核心級執行緒的不同優點:
核心可以同時在多個程序上排程來自同一程序的多個執行緒。
如果程序中的一個執行緒被阻塞,核心可以排程同一程序的另一個執行緒。
核心例程本身可以是多執行緒的。
核心級執行緒的缺點
核心執行緒的建立和管理通常比使用者執行緒慢。
從同一程序中的一個執行緒到另一個執行緒的控制轉移需要切換到核心模式。
執行緒控制塊 - TCB
執行緒控制塊(TCB)可以定義為作業系統核心中的資料結構,該結構主要包含有關執行緒的資訊。儲存在TCB中的特定於執行緒的資訊將突出顯示有關每個程序的一些重要資訊。
考慮以下與TCB中包含的執行緒相關的事項:
執行緒標識 - 它是分配給每個新執行緒的唯一執行緒ID(tid)。
執行緒狀態 - 它包含與執行緒的狀態(執行、可執行、不可執行、終止)相關的資訊。
程式計數器(PC) - 它指向執行緒的當前程式指令。
暫存器集 - 它包含分配給執行緒進行計算的暫存器值。
堆疊指標 - 它指向程序中的執行緒堆疊。它包含執行緒作用域內的區域性變數。
指向PCB的指標 - 它包含指向建立該執行緒的程序的指標。

程序與執行緒之間的關係
在多執行緒中,程序和執行緒是兩個非常密切相關的術語,具有相同的目標,即使計算機能夠一次執行多項操作。一個程序可以包含一個或多個執行緒,但相反,執行緒不能包含程序。然而,它們都仍然是兩個基本的執行單元。一個程式執行一系列指令,啟動程序和執行緒。
下表顯示了程序和執行緒之間的比較:
程序 | 執行緒 |
---|---|
程序是重量級或資源密集型的。 | 執行緒是輕量級的,比程序佔用更少的資源。 |
程序切換需要與作業系統互動。 | 執行緒切換不需要與作業系統互動。 |
在多處理環境中,每個程序執行相同的程式碼,但具有自己的記憶體和檔案資源。 | 所有執行緒可以共享相同的開啟檔案集、子程序等。 |
如果一個程序被阻塞,則在第一個程序解除阻塞之前,任何其他程序都無法執行。 | 當一個執行緒被阻塞並等待時,同一任務中的第二個執行緒可以執行。 |
不使用執行緒的多個程序使用更多資源。 | 多個執行緒程序使用更少的資源。 |
在多個程序中,每個程序獨立於其他程序執行。 | 一個執行緒可以讀取、寫入或更改另一個執行緒的資料。 |
如果父程序發生任何更改,則不會影響子程序。 | 如果主執行緒發生任何更改,則可能會影響該程序的其他執行緒的行為。 |
為了與兄弟程序通訊,程序必須使用程序間通訊。 | 執行緒可以直接與該程序的其他執行緒通訊。 |
多執行緒的概念
正如我們之前討論的那樣,多執行緒是CPU能夠透過同時執行多個執行緒來管理作業系統使用的一種能力。多執行緒的主要思想是透過將程序劃分為多個執行緒來實現並行。更簡單地說,我們可以說多執行緒是利用執行緒概念實現多工處理的一種方式。
可以透過以下示例理解多執行緒的概念。
示例
假設我們正在執行一個程序。該程序可能是為了開啟MS Word來編寫一些內容。在這樣的程序中,一個執行緒將被分配來開啟MS Word,另一個執行緒將需要進行寫入。現在,假設如果我們想編輯某些內容,則需要另一個執行緒來執行編輯任務,依此類推。
下圖幫助我們瞭解記憶體中如何存在多個執行緒:

我們可以在上圖中看到,在一個程序中可以存在多個執行緒,其中每個執行緒都包含自己的暫存器集和區域性變數。除此之外,程序中的所有執行緒共享全域性變數。
多執行緒的優點
現在讓我們看看多執行緒的一些優點。優點如下:
通訊速度 - 多執行緒提高了計算速度,因為每個核心或處理器同時處理單獨的執行緒。
程式保持響應 - 它允許程式保持響應,因為一個執行緒等待輸入,而另一個執行緒同時執行GUI。
訪問全域性變數 - 在多執行緒中,特定程序的所有執行緒都可以訪問全域性變數,如果全域性變數發生任何更改,則其他執行緒也可以看到。
資源利用率 - 在每個程式中執行多個執行緒可以更好地利用CPU,並且CPU的空閒時間減少。
資料共享 - 每個執行緒不需要額外的空間,因為程式內的執行緒可以共享相同的資料。
多執行緒的缺點
現在讓我們看看多執行緒的一些缺點。缺點如下:
不適合單處理器系統 - 與在多處理器系統上的效能相比,多執行緒難以在單處理器系統上實現計算速度方面的效能。
安全問題 - 正如我們所知,程式中的所有執行緒共享相同的資料,因此始終存在安全問題,因為任何未知執行緒都可以更改資料。
複雜度增加 − 多執行緒可以增加程式的複雜度,並且除錯變得困難。
可能導致死鎖狀態 − 多執行緒可能導致程式存在陷入死鎖狀態的風險。
需要同步 − 需要同步來避免互斥。這會導致更多的記憶體和CPU利用率。