天天看點

linux線程和程序詳解,線程詳解,以及linux下線程和程序的關系

線程:是程序中某個單一順序的控制流也稱為light weight processes)

線程是作業系統能夠進行運算排程的最小機關,她被包含在程序之中,是程序中的實際操作機關,一條線程指的是程序中一個單一順序的控制流,一個程序中可以并發多個線程,線程可以作業系統核心排程的核心線程。

同一個程序的多條線程将共享該程序中的全部系統資源,如虛拟位址空間,檔案描述符和信号處理等等

但是同一程序中的多個線程有各自的調用棧,自己的寄存器環境,自己的線程本地存儲。

線程和程序的差別在  :通常一個程序中可以包含多個線程,他們可以利用程序所擁有的資源,作業系統中,通常把程序作為配置設定資源的基本機關,把線程作為獨立運作和獨立排程的基本機關,猶豫線程比程序更小,基本不用有系統資源。

一個程序至少需要一個線程作為它的指令執行體,程序管理着資源(比如CPU,記憶體,檔案描述符等),線程将要配置設定到CPU上執行。

線程模型分為,核心級線程和使用者級線程兩種線程模型,分類的标準主要是線程的排程者是在核心内還是在外,前者更有利于并發使用多處理器的資源,後者更多考慮的是上下文切換開銷。

linux核心隻提供了輕量程序的支援,限制了更高效的線程模型的實作,但是linux着重

盡管linux支援輕量級程序,但并不能說,他就支援核心級程序,因為linux的線程和程序實際上處于一個排程層次,共享一個程序辨別符空間,這種限制不可能在linux下實作完全意義上的POSIX線程機制。

linux核心并不支援真正意義上的線程,linuxthreads使用和普通程序具有同樣核心排程視圖的輕量級程序來實作線程支援的。這些輕量級程序擁有獨立的程序ID,在程序排程,信号處理,IO等方面享有與普通程序一樣的能力。

linux下的線程就是輕量級程序。

每個linuxthread線程都同時具有線程id和程序id,其中程序id就是核心所維護的程序号

,而線程id則由linuxthreads配置設定和維護

__pthread_initial_thread的線程id為PTHREAD_THREADS_MAX,__pthread_manager_thread的是2*PTHREAD_THREADS_MAX+1,第一個使用者線程的線程id為PTHREAD_THREADS_MAX+2,此後第n個使用者線程的線程id遵循以下公式:

tid=n*PTHREAD_THREADS_MAX+n+1

這種配置設定方式保證了程序中所有的線程(包括已經退出)都不會有相同的線程id,而線程id的類型pthread_t定義為無符号長整型(unsigned long int),也保證了有理由的運作時間内線程id不會重複。

從線程id查找線程資料結構是在pthread_handle()函數中完成的,實際上隻是将線程号按PTHREAD_THREADS_MAX取模,得到的就是該線程在__pthread_handles中的索引。

5.線程的建立

在pthread_create()向管理線程發送REQ_CREATE請求之後,管理線程即調用pthread_handle_create()建立新線程。配置設定棧、設定thread屬性後,以pthread_start_thread()為函數入口調用__clone()建立并啟動新線程。pthread_start_thread()讀取自身的程序id号存入線程描述結構中,并根據其中記錄的排程方法配置排程。一切準備就緒後,再調用真正的線程執行函數,并在此函數傳回後調用pthread_exit()清理現場。

linux下檢視線程數的三種方法:

1. cat /proc/pid/status

2. pstree -p pid

3. top -H -p pid

4.ps xH,檢視所有存在的線程

5.ps -mp pid

6.ps -eLf |grep

linux線程和程式詳解,線程詳解,以及linux下線程和程式的關系

上面指令查詢結果的第二列為PID,第三列為PPID,第四列為LWP,第六列為NLWP。

jstack 30420 | less,然後查找 nid=0x44bf,哦,找到了

Shell代碼

linux線程和程式詳解,線程詳解,以及linux下線程和程式的關系

"main"prio=10tid=0x0000000053911400nid=0x44bfrunnable [0x0000000040f5c000..0x0000000040f5ced0]

java.lang.Thread.State: RUNNABLE

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at java.net.SocketInputStream.read(SocketInputStream.java:182)

at com.caucho.server.resin.Resin.waitForExit(Resin.java:524)

at com.caucho.server.resin.Resin.main(Resin.java:614)

jstack 指令告一段落,先不研究了