java學習:什麼是線程?最詳細的解釋

來源:互聯網
上載者:User
什麼是線程:有時也被成為輕量級進程,是程式執行流的最小單元。

一個標準的線程是由線程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<pthread.h>

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)線程可以喚醒條件變數,此時某個或所有等待此條件變數的線程都會被喚醒並繼續支援;

(也就是說,使用條件變數可以讓許多現車鞥一起等待某個事件的發生,當事件發生時,所有線程可以一起恢複執行)。

相關文章:

什麼是進程(process)?什麼是線程?

基於java學習中多線程的實現方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.