proc文件系統探索 之 以數字命名的目錄[三]

7.fd目錄fdinfo目錄
fd目錄包含了所有該進程使用的文件描述符,而fdinfo目錄包含的是對應的fd目錄中進程打開文件的操作權限。

niutao@niutao-desktop:/proc/6772/fd$ ls -l
lrwx------ 1 niutao niutao 64 2008-10-22 21:32 0 -> /dev/pts/5
lrwx------ 1 niutao niutao 64 2008-10-22 21:32 1 -> /dev/pts/5
lrwx------ 1 niutao niutao 64 2008-10-22 21:32 2 -> /dev/pts/5
niutao@niutao-desktop:/proc/6772/fd$ cd ../fdinfo/
niutao@niutao-desktop:/proc/6772/fdinfo$ cat 0
pos: 0
flags: 02

我 們可以看出fd目錄中包含的是進程打開文件的鏈接,這裏我們就可以看到我們經常提到的標準輸入(0),標準輸出(1),標準錯誤輸出(2)。那麼 fdinfo中包含的文件的含義,我們可以從這兩個方面探索。一個是內核中的 proc_fd_info函數(/fs/proc/base.c),fdinfo目錄中的文件中的內容正是由這個函數寫的,而flags對應的是文件結 構體(struct file)的f_flags域(知識我呢件的訪問權限)。另一個是我們可以通過查看fd目錄中包含的符號鏈接文件指向的文件的權限得知其(fdinfo目 錄中文件內容)含義:

niutao@niutao-desktop:/proc/6772/fd$ ls -l /dev/pts/5
crw--w---- 1 niutao tty 136, 5 2008-10-22 21:32 /dev/pts/5

“flags:02″表示文件訪問權限是O_RDWR(可讀可寫),而fd中符號鏈接文件指向的文件/dev/pts/5對用戶的權限也是可讀可寫。
8.root符號鏈接文件
該文件指向的是根目錄(/)。
9.stat文件
該文件的內容反應的是該進程的PCB(task_struct結構)的一些數據域的信息。下面我們來具體看一下它的含義。首先我們在終端上啓動gedit 程 序,然後使用系統監視器(gnome-system-monitor)查看gedit進程的pid爲11942,然後我們讀取它的stat文件

niutao@niutao-desktop:/proc/11942$ cat stat
11942 (gedit) S 7293 11942 7293 34820 11942 4202496 5017 0 0 0 80 10 0 0 20 0 1 0 1292037 61636608 4481 4294967295 134512640 135099420 3216990608 3216990068 3085931536 0 0 4096 0 0 0 0 17 0 0 0 0 0 0

在內核中,該文件的內容由do_task_stat函數(fs/proc/array.c)寫。主要操作是:

sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n"
,
task_pid_nr_ns(task, ns), /*進程(包括輕量級進程,即線程)(task->pid)*/
tcomm, /*應用程序的名字(task->comm)*/
state,/*進程的狀態信息(task->state),具體參見http://blog.chinaunix.net/u2/73528/showart_1106510.html*/
ppid,/*父進程ID*/
pgid,/*線程組ID*/
sid,/*會話組ID*/
tty_nr,/*該進程的tty終端的設備號,INT(34817/256)=主設備號,(34817-主設備號)=次設備號*/
tty_pgrp,/*終端的進程組號,當前運行在該進程所在終端的前臺進程(包括shell 應用程序)的PID*/
task->flags,/*進程標誌位,查看該進程的特性(定義在/include/kernel/sched.h中)*/
min_flt,/*累計進程的次缺頁數(Copy on Write頁和匿名頁)*/
cmin_flt,/*該進程所有的子進程發生的次缺頁的次數*/
maj_flt,/*主缺頁數(從映射文件或交換設備讀入的頁面數)*/
cmaj_flt,/*該進程所有的子進程發生的主缺頁的次數*/
cputime_to_clock_t(utime),/*該進程在用戶態運行的時間,單位爲jiffies*/
cputime_to_clock_t(stime),/*該進程在覈心態運行的時間,單位爲jiffies*/
cputime_to_clock_t(cutime),/*該進程所有的子進程在用戶態運行的時間總和,單位爲jiffies*/
cputime_to_clock_t(cstime),/*該進程所有的子進程在內核態運行的時間的總和,單位爲jiffies*/
priority,/*進程的動態優先級*/
nice,/*進程的靜態優先級*/.
num_threads,/*該進程所在的線程組裏線程的個數*/.
start_time,/*該進程創建的時間*/.
vsize,/*該進程的虛擬地址空間大小*/.
mm ? get_mm_rss(mm) : 0,/*該進程當前駐留物理地址空間的大小*/.
rsslim,/*該進程能駐留物理地址空間的最大值*/.
mm ? mm->start_code : 0,/*該進程在虛擬地址空間的代碼段的起始地址*/.
mm ? mm->end_code : 0,/*該進程在虛擬地址空間的代碼段的結束地址*/.
mm ? mm->start_stack : 0,/*該進程在虛擬地址空間的棧的結束地址*/.
esp,/*esp(32 位堆棧指針) 的當前值, 與在進程的內核堆棧頁得到的一致*/.
eip,/*指向將要執行的指令的指針, EIP(32 位指令指針)的當前值*/.
/* The signal information here is obsolete.
* It must be decimal for Linux 2.0 compatibility.
* Use /proc/#/status for real-time signals.

*/
task->pending.signal.sig[0] & 0x7fffffffUL,/*待處理信號的位圖,記錄發送給進程的普通信號*/.
task->blocked.sig[0] & 0x7fffffffUL,/*阻塞信號的位圖*/.
sigign .sig[0] & 0x7fffffffUL,/*忽略的信號的位圖*/.
sigcatch .sig[0] & 0x7fffffffUL,/*被俘獲的信號的位圖*/.
wchan,/*如果該進程是睡眠狀態,該值給出調度的調用點*/.
0UL,/*被swapped的頁數,當前沒用*/.
0UL,/*所有子進程被swapped的頁數的和,當前沒用*/.
task->exit_signal,/*該進程結束時,向父進程所發送的信號*/.
task_cpu(task),/*運行在哪個CPU上*/.
task->rt_priority,/*實時進程的相對優先級別*/.
task->policy,/*進程的調度策略,0=非實時進程,1=FIFO實時進程;2=RR實時進程*/.
(unsigned long long)delayacct_blkio_ticks(task),/**/.
cputime_to_clock_t(gtime),/**/.
cputime_to_clock_t(cgtime));/**/.

由以上解釋我們可以知道該進程的pid爲11942,可執行程序名爲gedit,當前正處於睡眠狀態,其父進程pid爲7293,按理說應該是一個終端(因爲我們是在終端上啓動gedit的),那麼我們來驗證一下:

bashniutao@niutao-desktop:/proc/7293$ cat stat
7293 (bash) S 7095 7293 7293 34820 7293 4194304 2902 40892 1 166 16 2 600 64 20 0 1 0 509398 6619136 918 4294967295 134512640 135194160 3214795824 3214792344 3086427152 0 0 3686404 1266761467 0 0 0 17 0 0 0 0 0 0

可 以看到pid等於7293的進程其可執行程序名的確是bash,所以它就是一個終端,並且是11942(gedit)的父進程。我們接着看11942號進 程。其所在線程組id爲11942,會話組id都爲7293,所以如果我們關閉pid爲7293的終端,則11942號進程也會被關閉。它的tty終端下 啓動的,所以終端設備號是一個有效值(如果是雙擊啓動的,那麼該項0,也就是說該程序不是在終端下啓動的)。終端的進程組號爲7293,該進程的 標誌爲4202496,對應十六進制爲0×402000。對於進程的標誌,內核定義在/include/linux/sched.h中,都已PF_開頭 (process flags),0×402000=PF_RANDOMIZE | PF_USED_MATH,表示沒有設置fpu的話,這個進程在使用任何變量之前都需初始化(PF_USED_MATH),並且該進程的虛擬地址空間是不 固定的(PF_RANDOMIZE )。接下來的4個(5017 0 0 0)是該進程的缺頁管理的統計,說明該進程發生了5017次次缺頁(次缺頁:Copy on Write頁和匿名頁)(min_flt),並且其所有子進程沒有發生次缺頁(cmin_flt),沒有發生主缺頁(主缺頁:從映射文件或交換設備 讀入的頁面數)(maj_flt),並且其所有子進程沒有發生住缺頁(cmaj_flt)。該進程在用戶態下運行的時間是80個jiffies(在我的系 統中jiffies等於250,所以80個jiffies爲20秒)(cputime_to_clock_t(utime)),該進程在內核態下運行的時 間是10個jiffies(2.5秒)(cputime_to_clock_t(stime)),該進程的所有子進程在用戶態下運行的時間爲 0(cputime_to_clock_t(cutime)),所有子進程在內核態下運行的時間爲 0(cputime_to_clock_t(cstime))。該進程的動態優先級爲20(priority),靜態優先級爲0(nice)。該進程所在 的線程組裏的線程個數爲1(num_threads)。接下來的一個”0″是直接輸出的,沒有含義。下面的1292037是該進程的的創建時間,說明該進 程的創建時間是開機後大約3.6小時時創建的(start_time=task->real_start_time,start_time/100 /3600=小時)。該進程的虛擬地址空間的大小是61636608B(),該進程當前主流物理內存空間的大小是4481B,能駐留物理地址空間的最大值 爲4294967295B(4GB),在虛擬地址空間的代碼段的起始地址是134512640(0×8048000,一般的應用程序虛擬地址空間的代碼段 的起始地址都是0x80xxxxx,可以使用objdump -d查看),虛擬地址空間的代碼段的結束地址是135099420(0x80D741C),虛擬地址空間的棧的起始地址是 3216990608(0xBFBF6190),堆棧指針的當前值爲3216990068(0xBFBF5F74),可見我的系統的堆棧的擴展方向是向下 擴展(每壓棧一個數,esp向下遞減)。下一條要執行的指令的地址是3085931536(0xB7EF9410)。接下來的7個(0 0 4096 0 0 0 0 )是與信號有關的,內核註釋說在這裏已經沒有作用,這裏就不做解釋。下面一個是進程退出時向父進程發送的信號,該出發送的信號爲SIGCHLD(17)。 下來一個0表示該進程運行在第0個cpu上。該進程的實時程的相對優先級別爲0,該進程是一個非實時進程。


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