什麼是執行緒:有時也被變成輕量級進程,是程式執行流的最小單元。
一個標準的執行緒是由執行緒ID,目前指令指標(PC)、暫存器集合和堆疊組成。
一個行程是由一個到多個執行緒組成,各個執行緒之間共享程式的記憶體空間(包括程式碼段,資料段的堆等)及一些行程級的資源(如開啟檔案和訊號)
多個執行緒可以互不干擾的並發執行,並共享進程的全域變數和堆的資料;
執行緒的存取權
執行緒的存取權限非常自由,可以存取進程記憶體裡的所有資料;
執行緒調度與優先權
單處理器對應多執行緒:作業系統讓這些多執行緒輪流執行,每次只執行一小段時間(通常是幾十秒),這樣每個執行緒「看起來」就像是在同時執行;這樣的一個處理器上不斷切換執行緒的操作成為「執行緒調度」
執行緒調度中的三種狀態:
(1):執行,此時執行緒正在執行
#(2# ):就緒,此時執行緒可以立即執行,但CPU已被佔用
(#3):等待,此時執行緒正在等待某一事件發生,無法執行
每當一個程式離開運行狀態,調度系統就會選擇一個就緒的執行緒執行;一個在等待狀態的執行緒事件發生以後進入就緒狀態。
在優先權排程的情況下,執行緒優先權的改變一般有三種方式:
使用者指定優先權;
根據進入等待狀態的頻繁程度提升或降低優先權;
長時間無法執行而被提升優先權;
Linux的多執行緒
在Linux下,可以用以下三個方法建立一個新的任務:
(1)fork:複製目前進程
(2)exec:使用新的可執行映像覆寫目前可執行映像
(3)clone:建立子進程,並從指定位置開始執行;
fork:
pid_t pid;
if(pid==fork()){…}
在fork呼叫以後,新的任務啟動並和本任務一起從fork函數返回,但不同的是本任務的fork將返回新任務的pid,而新任務的fork將返回0;
fork產生新任務的速度非常快,因為fork不複製原任務的記憶體空間,而是和原任務一起共享一個寫時拷貝的記憶體空間;
所謂#寫時拷貝:指的是兩個任務可以同時自由地讀取內存,但任一個任務試圖對內存進行修改時,內存就會複製一份提供給修改方單獨使用,以免影響到其他的任務使用;
fork只能夠產生本任務的鏡像,因此必須使用exec配合才能啟動別的新任務,exec可以用新的可執行映像取代目前的可執行映像,因此在fork產生了一個新任務之後,新任務可以呼叫exec來執行新的可執行檔;
頭檔都定義在pthread.h中
建立一個執行緒:#include
int pthread_create (pthread_t *thread,const pthread_attr_t* attr,void*(*start_routine)(void*),void*arg)
thread參數是新執行緒的識別符,後續的pthread_*函數透過它來引用新線程;
attr參數用來設定新執行緒的屬性,給它傳遞NULL表示使用預設執行緒屬性;
Start_routine 和arg參數分別制定新執行緒將執行的函數及參數;
pthread_create成功時返回0,失敗時返回錯誤碼;
結束一個執行緒:void pthread_exit(void *retval)
函數透過retval參數向執行緒的回收者傳遞其退出訊息;
執行緒安全性:
多執行緒程式處於一個多變的環境當中,可存取的全域變數和堆疊資料都可能隨時被其他的執行緒改變;
手段:同步與鎖定
原子的:單一指令運算稱為原子的,無論如何,單一指令的執行是不會被打斷的;
為了避免多個執行緒同時讀寫一個資料而產生不可預料的後果,我們要將各個執行緒對同一個資料的存取同步(所謂同步,就是在一個執行緒存取資料未結束時,其他執行緒不得對同一個資料進行存取),因此,對資料的存取被原子化;
同步的常見方法:(信號量、互斥量、臨界區,讀寫鎖定、條件變數)
鎖定:每個執行緒在存取資料或資源時首先試圖取得鎖,並在存取結束後釋放鎖定;
信號量:執行緒存取資源的時候先取得訊號量;
操作如下:
(1)將訊號量的值減1;
(2)如果訊號量的值小於0,則進入等待狀態;否則繼續執行;
存取完資源之後,執行緒釋放信號量;
(3)將信號量的值加1;
(4)如果信號量的值小於1,喚醒一個等待中的執行緒;
互斥量&&訊號量
##相同:資源僅同時允許一個線程訪問;異:信號量在整個系統中,可以被任意線程獲取並釋放,也就是說,同一個信號量可以被系統中的一個線程獲取後,另一個線程釋放;而互斥量要求哪個線程獲取了互斥量,哪個線程就要負責釋放這個鎖,其他線程越俎代庖去釋放互斥量是無效的;#臨界區:是比互斥量更嚴格的同步手段
把臨界區的鎖的取得稱為進入臨界區;而把鎖的釋放稱為離開臨界區。 區別(與信號量和互斥量)互斥量和信號量在系統的任何進程裡都是可見的;也就是說一個進程創建了一個互斥量或信號量,另一個進程試圖去獲取該鎖是合法的;臨界區的作用範圍僅限於本進程,其他的進程無法取得該鎖定讀取寫入鎖定:
兩種方法:共享的 獨佔的 當鎖定出於自由狀態時,試圖以任何一種方式取得鎖都能成功,並將鎖置於對應的狀態;(如上圖)條件變數:作為同步的一種手段,作用類似於一個柵欄;
對於條件變量,執行緒有兩種操作:(1)首先執行緒可以等待條件變量,一個條件變數可以被多個執行緒等待;( 2)執行緒可以喚醒條件變量,此時某個或所有等待此條件變數的執行緒都會被喚醒並繼續支援;#(也就是說,使用條件變數可以讓許多現車鞥一起等待某個事件的發生,當事件發生時,所有執行緒可以一起恢復執行)。 相關文章:以上是java學習:什麼是執行緒?最詳細的解釋的詳細內容。更多資訊請關注PHP中文網其他相關文章!