posix 線程(一):線程模型、pthread 系列函數 和 簡單多線程服務器端程序
一、線程有3種模型,分別是N:1用戶線程模型,1:1核心線程模型和N:M混合線程模型,posix thread屬於1:1模型。
(一)、N:1用戶線程模型
“線程實現”建立在“進程控制”機制之上,由用戶空間的程序庫來管理。OS內核完全不知道線程信息。這些線程稱為用戶空間線程。這些線程都工作在“進
程競爭范圍”(process contention scope):各個線程在同一進程競爭“被調度的CPU時間”(但不直接和其他進程中的線程競爭)。
在N:1線程模型中,內核不干涉線程的任何生命活動,也不干涉同一進程中的線程環境切換。
在N:1線程模型中,一個進程中的多個線程只能調度到一個CPU,這種約束限制了可用的並行總量。
第二個缺點是如果某個線程執行了一個“阻塞式”操作(如read),那么,進程中的所有線程都會阻塞,直至那個操作結束。為此,一些線程的實現是為
這些阻塞式函數提供包裝器,用非阻塞版本替換這些系統調用,以消除這種限制。
(二)、1:1核心線程模型 pthread線程庫--NPTL(Native POSIX Threading Library)
在1:1核心線程模型中,應用程序創建的每一個線程(也有書稱為LWP)都由一個核心線程直接管理。OS內核將每一個核心線程都調到系統CPU上,
因此,所有線程都工作在“系統競爭范圍”(system contention scope):線程直接和“系統范圍”內的其他線程競爭。
這種線程的創建與調度由內核完成,因為這種線程的系統開銷比較大(但一般來說,比進程開銷小)
(三)、N:M混合線程模型 NGPT(Next Generation POSIX Threads)

按照2003年3月NGPT官方網站上的通知,NGPT考慮到NPTL日益廣泛地為人所接受,為避免不同的線程庫版本引起的混亂,今后將不再進行進一步開發,而今進行支持性的維護工作。也就是說,NGPT已經放棄與NPTL競爭下一代Linux POSIX線程庫標准。
二、posix 線程概述
我們知道,進程在各自獨立的地址空間中運行,進程之間共享數據需要用進程間通信機制,有些情況需要在一個進程中同時執行多個控制流程,這時候
線程就派上了用場,比如實現一個圖形界面的下載軟件,一方面需要和用戶交互,等待和處理用戶的鼠標鍵盤事件,另一方面又需要同時下載多個文
件,等待和處理從多個網絡主機發來的數據,這些任務都需要一個“等待-處理”的循環,可以用多線程實現,一個線程專門負責與用戶交互,另外幾個線
程每個線程負責和一個網絡主機通信。
以前我們講過,main函數和信號處理函數是同一個進程地址空間中的多個控制流程,多線程也是如此,但是比信號處理函數更加靈活,信號處理函數的
控制流程只是在信號遞達時產生,在處理完信號之后就結束,而多線程的控制流程可以長期並存,操作系統會在各線程之間調度和切換,就像在多個進
程之間調度和切換一樣。由於同一進程的多個線程共享同一地址空間,因此Text Segment、Data Segment都是共享的,如果定義一個函數,在各線程
中都可以調用,如果定義一個全局變量,在各線程中都可以訪問到,除此之外,各線程還共享以下進程資源和環境:
文件描述符表
每種信號的處理方式(SIG_IGN、SIG_DFL或者自定義的信號處理函數)
當前工作目錄
用戶id和組id
但有些資源是每個線程各有一份的:
線程id
上下文,包括各種寄存器的值、程序計數器和棧指針
棧空間
errno變量
信號屏蔽字
調度優先級
我們將要學習的線程庫函數是由POSIX標准定義的,稱為POSIX thread或者pthread。在Linux上線程函數位於libpthread共享庫中,因此在編譯時要加上-lpthread選項。
參考:
《linux c 編程一站式學習》
《UNP》
《APUE》
http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/index.html
http://hi.baidu.com/_kouu/item/282b80a933ccc3a829ce9dd9