1. 線程概念
Linux裡的線程,也叫輕量級程序(light weight process),本質上是程序。
Linux早期是沒有線程的,後來的線程是借助程序實作的。線程、程序的核心都是調用系統的clone方法實作。
線程和程序的差別:(說明:PCB即程序控制塊)
程序擁有PCB,用于獨立的位址空間。是作業系統最小資源配置設定機關。(獨居位址空間)
線程也有PCB,但沒有獨立的位址空間,共享同一個位址空間。是作業系統最小執行機關。(合租位址空間)
Linux核心線程實作原理:
1)輕量級程序,也有PCB,建立線程使用的底層方法和程序一樣都是clone方法。
2)線程有各自的PCB,但是各自的PCB指向記憶體資源的三級頁表是相同的。是以位址空間是相同的,即共享位址空間。
3)線程可看作是寄存器和棧的集合。
三級頁表映射:程序PCB -> 頁目錄(可看作數組,首位址位于PCB裡)-> 頁表(可看作數組元素) -> 實體頁表 -> 記憶體單元
線程共享的資源:
檔案描述符、信号處理方式、目前工作目錄、使用者ID群組ID、記憶體位址空間(.text/.data/.bss/heap/so)
線程非共享的資源:
線程ID、處理器現場和核心棧指針、使用者空間棧、errno變量、信号屏蔽字、線程排程優先級、線程排程政策
2. pthread線程函數
pthread_t pthread_self(void);//擷取線程id,類似于程序的getpid()函數。
pthread_create(pthread_t* tid, pthread_attr_t* attr, void*(run)(void*), void* arg);//建立一個線程,類似于程序的fork()函數。
attr參數//線程屬性,需要調用pthread_attr_init()函數初始化,然後再設定屬性,最後調用pthread_attr_destroy()銷毀。
run參數//是一個函數指針,形式 void* run(void*){},是線程建立成功後的回調函數,該函數執行周期既是線程生命周期,即該函數執行完線程就結束。
arg參數//run函數的參數。
pthread_exit();//退出一個線程,類似于程序的exit()函數。
注意1:任一個線程裡調用exit()函數的話,程序退出,導緻所有線程都會退出。是以退出一個線程應該調用pthread_exit()函數。
注意2:主線程return傳回後,程序退出了,此時所有的子線程都會退出。
pthread_join();//主線程阻塞等待子線程退出,并擷取子線程退出狀态碼。類似于程序的wait()函數
pthread_detach();//使線程處于分離狀态,也就是說該線程執行完後自動釋放所有資源包括回收PCB。
pthread_cancel();//殺死、取消一個線程,類似于程序的kill()函數。
注意:調用該方法可能不會馬上殺死,需要到達一個取消點才會殺死。man 7 pthreads 檢視取消點。
pthread_testcancel();//通過代碼設定一個取消點。
pthread_equal();//比較兩個線程是否為相同。雖然現在linux線程id是一個unsigned long int,但是其他非linux系統或者後面版本linux可能改為結構體。
終止線程的三種方式:return、pthread_exit()、pthread_cancel()
3. pthread線程屬性
使用步驟、即初始化、使用、銷毀:
pthread_attr_t attr;
pthread_attr_init(&attr)
pthread_create(tid, &attr, callback_fun,callback_arg)
pthread_destroy(&attr)
pthread_attr_t結構體屬性:
線程分離:pthread_attr_getdetachstate()、pthread_attr_setdetachstate(PTHREAD_CREATE_DETACHED、PTHREAD_CREATE_JOINABLE)
線程棧位址:pthread_attr_getstack()、pthread_attr_setstack()
線程棧大小:pthread_attr_getstacksize()、pthread_attr_setstacksize()
4. 安裝pthread線程man page手冊
安裝指令:sudo apt-get install manpages-posix-dev
驗證安裝:man -k pthread 可以列出pthread
檢視目前pthread庫的版本:getconf GNU_LIBPTHREAD_VERSION
使用線程庫時,gcc編譯需要加上 -lpthread(小寫L)