如何查詢一個進程下面的線程數(進程和線程區別)
https://www.cnblogs.com/kevingrace/p/5252919.html
在平時工作中,經常會聽到應用程序的進程和線程的概念,那麼它們兩個之間究竟有什麼關係或不同呢?
一、對比進程和線程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 1)兩者概念 . 進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位. . 線程是指進程內的一個執行單元,也是進程內的可調度實體. 線程是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位線程自己基本上不擁有系統資源,只擁有一點 在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源. 2)兩者關係 . 一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以併發執行. . 相對進程而言,線程是一個更加接近於執行體的概念,它可以與同進程中的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。 3)兩者區別 進程和線程的主要差別在於它們是不同的操作系統資源管理方式:進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響;而線程只是一個進程中的不同執行路徑。 線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差 一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程。 進程和線程的區別: . 地址空間:線程是進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間; . 資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源 . 線程是處理器調度的基本單位,但進程不是. . 進程和線程二者均可併發執行. . 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程. . 線程的劃分尺度小於進程,使得多線程程序的併發性高。 . 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。 . 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個 線程執行控制。 . 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分可以同時執行。但操作系統並沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就 是進程和線程的重要區別。 4)優缺點 線程和進程在使用上各有優缺點: . 線程執行開銷小,但不利於資源的管理和保護;而進程正相反。 . 線程適合於在SMP機器上(即對稱多處理結構的簡稱,是指在一個計算機上彙集了一組處理器(多CPU),各CPU之間共享內存子系統以及總線結構)運行,而進程則可以跨機器遷移。 |
二、如何查看某個進程的線程數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 有些時候需要確定進程內部當前運行了多少線程,查詢方法如下: 1)通過pstree命令(根據pid)進行查詢: [root@xqsj_web2 ~] # ps -ef|grep java //查找進程pid(比如這裏查找java(tomcat)進程的pid) [root@xqsj_web2 ~] # pstree -p 19135 java(19135)─┬─{java}(19136) ├─{java}(19137) ....... └─{java}(13578) [root@xqsj_web2 ~] # pstree -p 19135|wc -l 46 // 由於第一行包括了2個線程,所以該進程下一共有47個線程! 或者使用 top 命令查看(可以查看到線程情況) [root@xqsj_web2 ~] # top -Hp 19135 //下面結果中的Tasks 對應的47即是線程的個數 top - 14:05:55 up 391 days, 20:59, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 47 total, 0 running, 47 sleeping, 0 stopped, 0 zombie Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.7% id , 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 8058056k total, 7718656k used, 339400k free , 354216k buffers Swap: 0k total, 0k used, 0k free , 4678160k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 19135 root 20 0 5339m 632m 5476 S 0.0 8.0 0:00.00 java 19136 root 20 0 5339m 632m 5476 S 0.0 8.0 0:00.84 java ...... 2)根據 ps 命令直接查詢: [root@xqsj_web2 ~] # ps hH p 19135| wc -l 47 3)通過查看 /proc/pid/status proc僞文件系統,它駐留在 /proc 目錄,這是最簡單的方法來查看任何活動進程的線程數。 /proc 目錄以可讀文本文件形式輸出,提供現有進程和系統硬件 相關的信息如CPU、中斷、內存、磁盤等等。 [root@xqsj_web2 ~] # cat /proc/19135/status Name: java State: S (sleeping) Tgid: 19135 Pid: 19135 PPid: 1 TracerPid: 0 ........ Threads: 47 // 這裏顯示的是進程創建的總線程數。輸出表明該進程有47個線程。 SigQ: 1 /62793 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 ....... voluntary_ctxt_switches: 1 nonvoluntary_ctxt_switches: 1 或者,也可以在 /proc//task 中簡單的統計子目錄的數量,如下所示: [root@xqsj_web2 ~] # ll /proc/19135/task 總用量 0 dr-xr-xr-x 6 root root 0 6月 14 17:57 11553 ...... [root@xqsj_web2 ~] # ll /proc/19135/task|wc -l 48 這是因爲,對於一個進程中創建的每個線程,在 /proc/ <pid> /task 中會創建一個相應的目錄,命名爲其線程ID。由此在 /proc/ <pid> /task 中目錄的總數表示在進程中線程的數目。 |
比如某臺服務器的CPU使用率飆升,通過top命令查看是gitlab程序佔用的cpu比較大,"ps -ef|grep gitlab"發現有很多個gitlab程序,現在需要查詢gitlab各個進程下的線程數情況。批量查詢命令如下:
# for pid in $(ps -ef|grep -v grep|grep gitlab|awk '{print $2}');do echo ${pid} > /root/a.txt ;cat /proc/${pid}/status|grep Threads > /root/b.txt;paste /root/a.txt /root/b.txt;done|sort -k3 -rn
腳本解釋:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1) for pid in $( ps -ef| grep - v grep | grep gitlab| awk '{print $2}' ) 定義${pid}變量爲gitlab進程的pid號 2) echo ${pid} > /root/a .txt 將http進程的pid號都打印到 /root/a .txt文件中 3) cat /proc/ ${pid} /status | grep Threads > /root/b .txt 將各個pid進程號下的線程信息打印到 /root/b .txt文件中 4) paste /root/a .txt /root/b .txt 以列的形式展示a.txt和b /txt 文件中的信息 5) sort -k3 -rn -k3 表示以第三列進行排序 -rn 表示降序 |