如何查询一个进程下面的线程数(进程和线程区别)
?
在平時工作中,經常會聽到應用程序的進程和線程的概念,那么它們兩個之間究竟有什么關系或不同呢?
一、對比進程和線程
1)兩者概念
-? 進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.
-? 線程是指進程內的一個執行單元,也是進程內的可調度實體. 線程是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
2)兩者關系
-? 一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以并發執行.
-? 相對進程而言,線程是一個更加接近于執行體的概念,它可以與同進程中的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。
3)兩者區別
-? 進程和線程的主要差別在于它們是不同的操作系統資源管理方式:進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產生影響;而線程只是一個進程中的不同執行路徑。
-? 線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些.?但對于一些要求同時進行并且又要共享某些變量的并發操作,只能用線程,不能用進程。
進程和線程的區別
-? 地址空間:線程是進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
-? 資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
-? 線程是處理器調度的基本單位,但進程不是.
-? 進程和線程二者均可并發執行.
-? 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.
-? 線程的劃分尺度小于進程,使得多線程程序的并發性高。
-? 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
-? 線程在執行過程中與進程是有區別的。每個獨立的線程有一個程序運行入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
-? 從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。但操作系統并沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。
4)優缺點
線程和進程在使用上各有優缺點:
-? 線程執行開銷小,但不利于資源的管理和保護;而進程正相反。
-? 線程適合于在SMP機器上(即對稱多處理結構的簡稱,是指在一個計算機上匯集了一組處理器(多CPU),各CPU之間共享內存子系統以及總線結構)運行,而進程則可以跨機器遷移。
二、如何查看某個進程的線程數
有些時候需要確定進程內部當前運行了多少線程,查詢方法如下: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 cachedPID 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 473)通過查看/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)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 表示降序? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?來看個cup使用率告警問題處理案例? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
jstack命令生成的thread dump信息包含了JVM中所有存活的線程,為了分析指定線程,必須找出對應線程的調用棧,應該如何找?
在top命令中,已經獲取到了占用cpu資源較高的線程pid,將該pid轉成16進制的值,在thread dump中每個線程都有一個nid,找到對應的nid即可;隔段時間再執行一次stack命令獲取thread dump,區分兩份dump是否有差別,在nid=0x246c的線程調用棧中,發現該線程一直在執行JstackCase類第33行的calculate方法,得到這個信息,就可以檢查對應的代碼是否有問題。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
獲取進程pid的方法 [root@ansible-server ~]# ps -ef|grep nginx root 2148 1 0 2018 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf root 16517 16179 0 11:09 pts/1 00:00:00 grep nginx nginx 21091 2148 0 Jan27 ? 00:00:00 nginx: worker process 使用"ps x" [root@ansible-server ~]# ps x | grep nginx2148 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf 16526 pts/1 S+ 0:00 grep nginx[root@ansible-server ~]# ps x | grep nginx|grep -v grep|awk '{print $1}' 2148使用"pgrep" [root@ansible-server ~]# pgrep nginx 2148 21091[root@ansible-server ~]# pgrep -f nginx 2148 21091使用pidof [root@ansible-server ~]# pidof nginx 21091 2148使用pstree [root@ansible-server ~]# pstree -p | grep nginx|-nginx(2148)---nginx(21091)轉載于:https://www.cnblogs.com/kevingrace/p/5252919.html
總結
以上是生活随笔為你收集整理的如何查询一个进程下面的线程数(进程和线程区别)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Fragment 与 Fragment
- 下一篇: docker环境下的测试