一文帶你快速掌握進程與線程的根本(附線程同步源碼)

基本概念:


        線程(英語:thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。同一進程中的多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符信號處理等等。但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。一個進程可以有很多線程,每條線程並行執行不同的任務。

 

與進程的區別:


        進程是資源分配的基本單位。所有與該進程有關的資源,都被記錄在進程控制塊PCB中。以表示該進程擁有這些資源或正在使用它們。另外,進程也是搶佔處理機的調度單位,它擁有一個完整的虛擬地址空間。當進程發生調度時,不同的進程擁有不同的虛擬地址空間,而同一進程內的不同線程共享同一地址空間。與進程相對應,線程與資源分配無關,它屬於某一個進程,並與進程內的其他線程一起共享進程的資源。線程只由相關堆棧系統棧或用戶棧寄存器和線程控制表TCB組成。寄存器可被用來存儲線程內的局部變量,但不能存儲其他線程的相關變量。

        通常在一個進程中可以包含若干個線程,它們可以利用進程所擁有的資源。在引入線程的操作系統中,通常都是把進程作爲分配資源的基本單位,而把線程作爲獨立運行和獨立調度的基本單位。由於線程比進程更小,基本上不擁有系統資源,故對它的調度所付出的開銷就會小得多,能更高效的提高系統內多個程序間併發執行的程度,從而顯著提高系統資源的利用率和吞吐量。x線程與進程的區別可以歸納爲以下4點:

      1)地址空間和其它資源(如打開文件):進程間相互獨立,同一進程的各線程間共享。某進程內的線程在其它進程不可見。

      2)通信:進程間通信IPC,線程間可以直接讀寫進程數據段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數據的一致性。

     3)調度和切換:線程上下文切換比進程上下文切換要快得多。

     4)在多線程OS中,進程不是一個可執行的實體。

 

線程同步:


        線程是進程中的實體,一個進程可以擁有多個線程,一個線程必須有一個父進程。線程不擁有系統資源,只有運行必須的一些數據結構;它與父進程的其它線程共享該進程所擁有的全部資源。線程可以創建和撤消線程,從而實現程序的併發執行。一般,線程具有就緒阻塞運行三種基本狀態。

        在多中央處理器系統裏,不同線程可以同時在不同的中央處理器上運行,甚至當它們屬於同一個進程時也是如此。大多數支持多處理器的操作系統都提供編程接口來讓進程可以控制自己的線程與各處理器之間的關聯度(affinity)。

       有時候,線程也稱作輕量級進程。就象進程一樣,線程在程序中是獨立的、併發的執行路徑,每個線程有它自己的堆棧、自己的程序計數器和自己的局部變量。但是,與分隔的進程相比,進程中的線程之間的隔離程度要小。它們共享內存文件句柄和其它每個進程應有的狀態。

        進程可以支持多個線程,它們看似同時執行,但互相之間並不同步。一個進程中的多個線程共享相同的內存地址空間,這就意味着它們可以訪問相同的變量對象,而且它們從同一堆中分配對象。儘管這讓線程之間共享信息變得更容易,但您必須小心,確保它們不會妨礙同一進程裏的其它線程。

 

線程狀態


新線程態(New Thread)

產生一個Thread對象就生成一個新線程。當線程處於"新線程"狀態時,僅僅是一個空線程對象,它還沒有分配到系統資源。因此只能啓動或終止它。任何其他操作都會引發異常。例如,一個線程調用了new方法之後,並在調用start方法之前的處於新線程狀態,可以調用start和stop方法。

可運行態

start()方法產生運行線程所必須的資源,調度線程執行,並且調用線程的run()方法。在這時線程處於可運行態。該狀態不稱爲運行態是因爲這時的線程並不總是一直佔用處理機。特別是對於只有一個處理機的PC而言,任何時刻只能有一個處於可運行態的線程佔用處理 機。Java通過調度來實現多線程處理機的共享。注意,如果線程處於Runnable狀態,它也有可能不在運行,這是因爲還有優先級和調度問題。

 

線程創建:


在Linux系統中,POSIX線程(Pthreads)的頭文件是<pthread.h>

1. 創建線程

Int  pthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);

2. 等待線程

Int  pthread_join(pthread_tthread,void**retval);

3. 退出線程

Void pthread_exit(void*retval);

4. 返回當前線程的線程標識符

pthread_tpthread_self(void);

5. 線程取消

Int  pthread_cancel(pthread_tthread);Win32線程

Windows操作系統,Win32線程的頭文件是<Windows.h>

1.創建線程

HANDLE  WINAPI CreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,SIZE_TdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);

2.結束本線程

VOID  WINAPI  ExitThread(DWORDdwExitCode);

3.掛起指定的線程

DWORD  WINAPI  SuspendThread(HANDLEhThread);

4.恢復指定線程運行

DWORD  WINAPI  ResumeThread(HANDLEhThread);

5.等待線程運行完畢

DWORD  WINAPI  WaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);

6.返回當前線程的線程標識符

DWORD  WINAPI  GetCurrentThreadId(void);

7.返回當前線程的線程句柄

HANDLE  WINAPI  GetCurrentThread(void);

 

地址:https://download.csdn.net/download/fengxianghui01/12413311

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章