爲何線程有PID?Linux上查看某個進程內存佔用情況

在linux下用 top -H -p <pid> 查詢某個進程的線程
按理說,都是某個進程下的線程, 應該進程id PID一樣啊,但實際卻都不一樣


實際是被PID的名字給弄混了,線程進程都會有自己的ID,這個ID就叫做PID,PID是不特指進程ID,線程ID也可以叫做PID。

pthread庫裏的每一個線程都對應一個內核線程,都是有單獨的pid。

 

The four threads will have the same PID but only when viewed from above. What you (as a user) call a PID is not what the kernel (looking from below) calls a PID.

In the kernel, each thread has it's own ID, called a PID (although it would possibly make more sense to call this a TID, or thread ID) and they also have a TGID (thread group ID) which is the PID of the thread that started the whole process.

Simplistically, when a new process is created, it appears as a thread where both the PID and TGID are the same (new) number.

When a thread starts another thread, that started thread gets its own PID (so the scheduler can schedule it independently) but it inherits the TGID from the original thread.

That way, the kernel can happily schedule threads independent of what process they belong to, while processes (thread group IDs) are reported to you.

關於線程繼承關係圖如下:

 
  1. USER VIEW
  2. <-- PID 43 --> <----------------- PID 42 ----------------->
  3. +---------+
  4. | process |
  5. _| pid=42 |_
  6. _/ | tgid=42 | \_ (new thread) _
  7. _ (fork) _/ +---------+ \
  8. / +---------+
  9. +---------+ | process |
  10. | process | | pid=44 |
  11. | pid=43 | | tgid=42 |
  12. | tgid=43 | +---------+
  13. +---------+
  14. <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
  15. KERNEL VIEW
 

在這裏你可以清晰的看到,創建一個新的進程會給一個新的PID和TGID,並且2個值相同,當創建一個新的線程的時候,會給你一個新的PID,並且TGID和之前開始的進程一致。

Linux通過進程查看線程的方法 1).htop按t(顯示進程線程嵌套關係)和H(顯示線程) ,然後F4過濾進程名。2).ps -eLf | grep java(快照,帶線程命令,e是顯示全部進程,L是顯示線程,f全格式輸出) 3).pstree -p <pid>(顯示進程樹,不加pid顯示所有) 4).top -Hp <pid> (實時) 5).ps -T -p <pid>(快照) 推薦程度按數字從小到大。

打印線程的PID的方法如下:
 
getpid()方法可以打印進程的PID
gettid()方法可以打印線程的PID

void * thread_start(void *arg)  
{  
    printf("Process ID: %d, thread ID %d\n", getpid(), gettid());  
}  
由於gettid()在glibc中沒有包含
Note: There is no glibc wrapper for this system call; see NOTES. 
 
所以用如下syscall函數在用戶空間替代gettid()的功能
syscall(__NR_gettid))   或者  syscall(SYS_gettid)
 
在文件 /usr/include/bits/syscall.h裏, 有一行:
#define SYS_gettid __NR_gettid  
可見二者是一樣的。__NR_gettid是系統調用號
 
#include <pthread.h>  
#include <stdio.h>  
#include <sys/types.h>  
#include <sys/syscall.h>  
#include <unistd.h>  


void * thread_start(void *arg)  
{  
    printf("[1] Process ID: %d, thread ID %d\n", getpid(), syscall(__NR_gettid));  
    printf("[2] Process ID: %d, thread ID %d\n", getpid(), syscall(SYS_gettid));  
}  
 
Linux 上進行開發和運營維護的時候,免不了要查看某一個程序所佔用內存的情況。有很多個命令都可以達到我們的需求,這裏給大家列舉幾個:

 

1:cat /proc/pid/status

在這裏插入圖片描述

2:ps -aux | grep pid

在這裏插入圖片描述

3:top -p pid 查看程序的情況

PID:進程的ID
USER:進程所有者
PR:進程的優先級別,越小越優先被執行
NInice:值
VIRT:進程佔用的虛擬內存
RES:進程佔用的物理內存
SHR:進程使用的共享內存
S:進程的狀態。S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值爲負數
%CPU:進程佔用CPU的使用率
%MEM:進程使用的物理內存和總內存的百分比
TIME+:該進程啓動後佔用的總的CPU時間,即佔用CPU使用時間的累加值。
COMMAND:進程啓動命令名稱
在這裏插入圖片描述

這裏會打印出當前進程詳細的情況,其中,佔用內存是 VmRSS 127884kb。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章