linux沒有真正意義上的執行緒,它的實現是由程序來模擬,所以屬於使用者級執行緒,位於libpthread共享庫(所以執行緒的id只在庫中有效),遵循posix標準。
windows下有乙個真正的資料結構tcb來描述執行緒。
linux上兩個最有名的執行緒庫linuxthreads和nptl。
linux兩個執行緒模型的比較:
linux執行緒模型的比較
linux下多執行緒虛擬位址空間的對映類似於用vfork建立多個子程序。
程序:程式的乙個動態執行例項,承擔分配系統資源的例項。(linux實現程序的主要目的是資源獨佔)
執行緒:在程序的內部執行(程序的位址空間)執行的乙個分支,也是排程的基本單位(排程按lwp排程)。(linux實現執行緒的主要目的是資源共享)
執行緒所有的資源由程序提供。
單程序:只有乙個程序的執行緒(lwp=pid)。
lwp:輕量級程序。
由於同一程序的多個執行緒共享同一位址空間,因 此text segment、data segment都是共享的,如果定義乙個函式,在各執行緒中都可以呼叫,如果定義乙個全域性變數,在各執行緒中都可以訪問到,除此之外,各執行緒還共享以下程序資源和環境:
1. 檔案描述符表但有些資源是每個執行緒各有乙份的:2. 每種訊號的處理方式(sig_ign、sig_dfl或者自定義的訊號處理函式)
3. 當前工作目錄
4. 使用者id和組id
1.執行緒id1. 多個2. 上下文資訊,包括各種暫存器的值、程式計數器和棧指標
3. 棧空間
4. errno變數
5. 訊號遮蔽字
6. 排程優先順序
執行緒,它們彼此之間使用相同的位址空間,共享大部分資料,啟動乙個執行緒所花費的空間遠遠小於啟動乙個程序所花費的空間,
而且,執行緒間彼此切換所需的時間也遠遠小於程序間切換所需要的時間,建立銷毀速度快。
2.是執行緒間方便的通訊機制。由於同一程序下的執行緒之間共享資料空間,所以乙個執行緒的資料可以直接為其它執行緒所用,這不僅快捷,而且
方便。在linux系統下,與執行緒相關的函式都定義在pthread.h標頭檔案中。
#include int pthread_create(pthread_t * thread, const pthread_arrt_t* attr,void*(*start_routine)(void *), void* arg);
(1)thread引數是新執行緒的識別符號,為乙個整型。
(2)attr引數用於設定新執行緒的屬性。給傳遞null表示設定為預設執行緒屬性。
(3)start_routine和arg引數分別指定新執行緒將執行的函式和引數。start_routine返回時,這個執行緒就退出了
(4)返回值:成功返回0,失敗返回錯誤號。
執行緒id的型別是thread_t,它只在當前程序中保證是唯一的,在不同的系統中thread_t這個型別有不同的實現,呼叫pthread_self()可以獲得當前執行緒的id
程序id的型別時pid_t,每個程序的id在整個系統中是唯一的,呼叫getpid()可以獲得當前程序的id,是乙個正整數值。
終止某個執行緒而不終止整個程序,可以有三種方法:
1. 從執行緒函式return。這種方法對主線程不適應,從main函式return相當於呼叫exit。
2. 乙個執行緒可以呼叫pthread_cancel終止同一程序中的另乙個執行緒。
3. 執行緒可以呼叫pthread_exit終止自己。
#include int pthread_cancel(pthread_t thread);
(1)thread引數是目標執行緒的識別符號。
(2)該函式成功返回0,失敗返回錯誤碼。
#include void pthread_exit(void * retval);
(2)pthread_exit函式通過retval引數向執行緒的**者傳遞其退出資訊。它執行之後不會返回到呼叫者,且永遠不會失敗。
#include void pthread_join(pthread_t thread,void ** retval);
(1)呼叫該函式的執行緒將掛起等待,直到id為thread的執行緒終止。
(2)thread執行緒以不同的方法終止,通過pthread_join得到的終止狀態是不同的,
總結如下:
1. 如果thread執行緒通過return返回,value_ptr所指向的單元裡存放的是thread執行緒函式的返回值。
2. 如果thread執行緒被別的執行緒呼叫pthread_cancel異常終掉,value_ptr所指向的單元裡存放的是常數pthread_canceled。
3. 如果thread執行緒是自己呼叫pthread_exit終止的,value_ptr所指向的單元存放的是傳給pthread_exit的引數。 如果對thread執行緒的終止狀態不感興趣,可以傳null給value_ptr引數。
(3)成功返回0,失敗返回錯誤碼。可能出現的錯誤碼:
1.在任何乙個時間點上,執行緒是可結合的(joinable)或者是分離的(detached)。
2.乙個可結合的執行緒能夠被其他執行緒收回其資源和殺死。在被其他執行緒**之前,它的儲存器資源
(例如棧)是不釋放的。(預設情況下執行緒的建立都是可結合的)
3.乙個分離的執行緒是不能被其他執行緒**或殺死的,它的儲存器 資源在它終止時由系統自動釋放。
4. 如果乙個可結合執行緒結束執行但沒有被join,會導致部分資源沒有被**,所以建立執行緒者應該呼叫pthread_join來等待執行緒執行結束,並可得到執行緒的退出**,**其資源。
呼叫pthread_join後,如果該執行緒沒有執行結束,呼叫者會被阻塞。如何解決這種情況呢?
例如,在web伺服器中當主線程為每個新來的連線請求建立乙個子執行緒進行處理的時候,主線程並不希望因為呼叫pthread_join而阻塞(因為還要繼續處理之後到來的連線請求),這時可以在子執行緒中加入** pthread_detach(pthread_self())或者父執行緒呼叫pthread_detach(thread_id)(非阻塞,可立即返回)這將該子執行緒的狀態設定為分離的(detached),如此一來,該執行緒執行結束後會自動釋放所有資源。
驗證**:
#include #include #include #include void* thread_run(void* _val)
int main()
else
}else
}
執行結果:
分析:可以看到被分離的執行緒不可以被等待;乙個執行緒初始為可結合的,要麼在父執行緒等待或分離,要麼在子執行緒分離,只能採取上述幾種措施的一種。
多執行緒程式設計小結(一)
1.背景知識 linux沒有真正意義上的執行緒,它的實現是由程序來模擬,所以屬於使用者級執行緒,位於libpthread共享庫 所以執行緒的id只在庫中有效 遵循posix標準。windows下有乙個真正的資料結構tcb來描述執行緒。linux上兩個最有名的執行緒庫linuxthreads和nptl...
linux多執行緒程式設計小結 一
執行緒是程序基本的基本排程單位。而程序是程式執行和資源分配的最小單位。可以減少資源的開銷.執行緒有專門的執行緒庫來呼叫thread.執行緒的建立用thread create int pthread create pthread t restrict thread,const pthread attr...
linux多執行緒程式設計小結 三
第二節 計時等待 int pthread cond timewait pthread cond t cond,pthread mutex mutex,const timespec abstime 啟用乙個等待該條件的執行緒 存在多個等待執行緒時按入隊順序啟用其中乙個 int pthread cond...