內容

名稱

執行緒 - 處理 Perl 中的執行緒 (僅適用於舊程式碼)

已棄用

Thread 模組用作舊式執行緒模型 (稱為 5005threads) 的前端,該模型是在 5.005 版中引入的。該模型已棄用,並已在 5.10 版中移除。

對於舊程式碼和臨時向後相容性,Thread 模組已重新設計,以作為新解釋器執行緒 (ithreads) 模型的前端。但是,某些先前的功能不可用。此外,兩個執行緒模型之間的資料共用模型完全不同,任何與資料共用相關的事項都必須以不同的方式思考。使用 ithreads 時,您必須明確在執行緒之間 share() 變數。

強烈建議您盡快將任何現有的執行緒程式碼移轉到新的模型 (即使用 threadsthreads::shared 模組)。

歷史

在 Perl 5.005 中,執行緒模型是所有資料都隱含共用,並且必須明確同步對資料的共用存取。此模型稱為 5005threads

在 Perl 5.6 中,引入了新的模型,其中所有內容都是執行緒本機,並且必須明確宣告對資料的共用存取。此模型稱為 ithreads,代表「解釋器執行緒」。

在 Perl 5.6 中,ithreads 模型並未作為公開 API 提供;僅作為內部 API,供延伸模組撰寫人員使用,並在 Win32 平台上實作 fork() 模擬。

在 Perl 5.8 中,ithreads 模型透過 threads 模組提供,而 5005threads 模型已棄用。

在 Perl 5.10 中,5005threads 模型已從 Perl 解釋器中移除。

語法

use Thread qw(:DEFAULT async yield);

my $t = Thread->new(\&start_sub, @start_args);

$result = $t->join;
$t->detach;

if ($t->done) {
    $t->join;
}

if($t->equal($another_thread)) {
    # ...
}

yield();

my $tid = Thread->self->tid;

lock($scalar);
lock(@array);
lock(%hash);

my @list = Thread->list;

說明

Thread 模組為 Perl 提供多執行緒支援。

函式

$thread = Thread->new(\&start_sub)
$thread = Thread->new(\&start_sub, LIST)

new 在引用的子常式中啟動執行緒的新執行緒。選用清單作為參數傳遞給子常式。執行會持續在子常式和 new 呼叫後的程式碼中。

Thread->new 回傳一個執行緒物件,代表新建立的執行緒。

lock VARIABLE

lock 在變數上放置鎖定,直到鎖定範圍結束。

如果變數被另一個執行緒鎖定,lock 呼叫會封鎖直到變數可用。lock 是遞迴的,因此可以安全地多次呼叫 lock--變數會保持鎖定狀態,直到變數最外層的鎖定範圍結束。

變數鎖定只會影響 lock 呼叫--不會 影響對變數的正常存取。(子常式的鎖定不同,稍後會說明。)如果你真的、真的 希望鎖定封鎖存取,那就繼續吧,將它們綁定到某個東西並自行管理。這是故意的。雖然管理變數存取是一件好事,但 Perl 不會強迫你離開它的起居室...

如果容器物件(例如雜湊或陣列)被鎖定,該容器的所有元素都不會被鎖定。例如,如果執行緒執行 lock @a,任何其他執行緒執行 lock($a[12]) 都不會封鎖。

最後,lock 將只會向上追溯參考一個 層級。lock(\$a) 等同於 lock($a),而 lock(\\$a) 則不等於。

async BLOCK;

async 建立一個執行緒來立即執行緊接在它之後的區塊。這個區塊被視為一個匿名子常式,因此在閉合大括號後必須加上分號。就像 Thread->newasync 會回傳一個執行緒物件。

Thread->self

Thread->self 函式會回傳一個執行緒物件,代表執行 Thread->self 呼叫的執行緒。

Thread->list

傳回所有未加入、未分離的 Thread 物件清單。

cond_wait VARIABLE

cond_wait 函數會將一個已鎖定的變數作為參數,解鎖該變數,並封鎖,直到另一個執行緒對同一個已鎖定變數執行 cond_signalcond_broadcast 為止。cond_wait 封鎖的變數會在 cond_wait 滿足後重新鎖定。如果有多個執行緒在同一個變數上執行 cond_wait,除了其中一個之外,其他執行緒都會重新封鎖,等待重新取得變數的鎖定。(因此,如果你只使用 cond_wait 進行同步,請盡快放棄鎖定。)

cond_signal VARIABLE

cond_signal 函數會將一個已鎖定的變數作為參數,並解除一個在該變數上執行 cond_wait 的執行緒的封鎖。如果有多個執行緒在該變數上執行 cond_wait 而被封鎖,只會解除其中一個執行緒的封鎖(哪一個執行緒會被解除封鎖是不確定的)。

如果沒有執行緒在該變數上執行 cond_wait 而被封鎖,則會捨棄該訊號。

cond_broadcast VARIABLE

cond_broadcast 函數的運作方式類似於 cond_signal。不過,cond_broadcast 會解除在已鎖定變數上執行 cond_wait 而被封鎖的所有執行緒的封鎖,而不只解除一個執行緒的封鎖。

yield

yield 函數允許另一個執行緒取得 CPU 的控制權。確切的結果取決於實作。

方法

join

join 會等待執行緒結束,並傳回執行緒結束時傳出的任何值。join 會封鎖,直到執行緒結束為止,但如果執行緒已經終止,則不會封鎖。

如果執行 join 的執行緒die了,則會在此刻傳回執行緒die時傳出的錯誤。如果你不希望執行 join 的執行緒也die,則應該將 join 包裝在 eval 中,或使用 eval 執行緒方法,而不是 join

detach

detach 會告訴執行緒它永遠不會被加入,也就是說,一旦執行緒停止執行,就可以移除其存在的所有痕跡。分離執行緒中的錯誤不會在任何地方可見 - 如果你想要捕捉這些錯誤,你應該使用 $SIG{__DIE__} 或類似的東西。

equal

equal 會測試兩個執行緒物件是否代表同一個執行緒,如果它們代表同一個執行緒,則傳回 true。

tid

tid 方法會傳回執行緒的 tid。tid 是在建立執行緒時指定的單調遞增整數。程式的主執行緒的 tid 會是零,而後續執行緒的 tid 會從一開始指定。

done

done 方法會傳回 true,如果你正在檢查的執行緒已完成,否則傳回 false。

已廢棄

以下功能已在 5005threads 中實作,但不再適用於 ithreads

lock(\&sub)

在 5005threads 中,你也可以 lock 一個子程式,讓來自其他執行緒對該子程式的任何呼叫都會被封鎖,直到鎖定解除。

此外,子程式可以用 :locked 屬性宣告,這會序列化對子程式的存取,但允許不同執行緒非同時存取。

eval

eval 方法會在 join 周圍包住一個 eval,因此會等待執行緒退出,傳遞執行緒可能傳回的任何值,並將任何錯誤放入 $@

flags

flags 方法會傳回執行緒的旗標,一個對應於執行緒內部旗標的整數值。

另請參閱

threadsthreads::sharedThread::QueueThread::Semaphore