深入理解proc文件系统
概述:linux 内核提供了一种获取其内部数据结构和在系统运行时改变内核参数设置的方法,这种方法就是凭借proc文件系统。
1.proc ——一个虚拟文件系统
proc文件系统用来提供给内核和内核模块发送消息给进程,之所以说它是虚拟的文件系统,是因为1)虚拟是指的是它没有对应具体的存储介质,比如磁盘;2)文件系统指的是它的确实现了必须的文件系统接口。可以通过如下命令查询:
[cpp]
$ mount -l
/dev/sda10 on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
2.proc一级目录概览
/proc/cpuinfo
/proc/meminfo
/proc/mounts----mounted fs
/proc/devices----avaiable devices
/proc/filesystems----supported file systems
/proc/modules----loaded modules
/proc/version-----kernel version
/proc/cmdline----parameters passed to the kernel at the time of starting
3. 特定进程的相关信息
如果要知道某个进程的相关信息:环境变量,对应的应用程序,cpu占用时间,进程状态等等,可以使用proc文件系统进行查询。例如:
$ ll /proc/2184
total 0
dr-xr-xr-x 8 hyk hyk 0 6月 17 20:51 ./
dr-xr-xr-x 214 root root 0 6月 18 04:50 ../
dr-xr-xr-x 2 hyk hyk 0 6月 18 10:27 attr/
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 autogroup
-r-------- 1 hyk hyk 0 6月 17 20:51 auxv
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 cgroup
--w------- 1 hyk hyk 0 6月 18 10:27 clear_refs
-r--r--r-- 1 hyk hyk 0 6月 17 20:51 cmdline
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 comm
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 coredump_filter
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 cpuset
lrwxrwxrwx 1 hyk hyk 0 6月 18 10:27 cwd -> /home/hyk/
-r-------- 1 hyk hyk 0 6月 17 20:51 environ
lrwxrwxrwx 1 hyk hyk 0 6月 17 20:51 exe -> /usr/lib/gnome-settings-daemon/gnome-settings-daemon*
dr-x------ 2 hyk hyk 0 6月 17 20:51 fd/
dr-x------ 2 hyk hyk 0 6月 18 10:27 fdinfo/
-r-------- 1 hyk hyk 0 6月 18 10:27 io
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 latency
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 limits
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 loginuid
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 maps
-rw------- 1 hyk hyk 0 6月 18 10:27 mem
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 mountinfo
-r--r--r-- 1 hyk hyk 0 6月 17 20:51 mounts
-r-------- 1 hyk hyk 0 6月 18 10:27 mountstats
dr-xr-xr-x 5 hyk hyk 0 6月 18 10:27 net/
dr-x--x--x 2 hyk hyk 0 6月 18 10:27 ns/
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 oom_adj
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 oom_score
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 oom_score_adj
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 pagemap
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 personality
lrwxrwxrwx 1 hyk hyk 0 6月 18 10:27 root -> //
-rw-r--r-- 1 hyk hyk 0 6月 18 10:27 sched
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 schedstat
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 sessionid
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 smaps
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 stack
-r--r--r-- 1 hyk hyk 0 6月 17 20:51 stat
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 statm
-r--r--r-- 1 hyk hyk 0 6月 17 20:51 status
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 syscall
dr-xr-xr-x 7 hyk hyk 0 6月 18 10:27 task/
-r--r--r-- 1 hyk hyk 0 6月 18 10:27 wchan
相关选项的说明如下:
cmdline:启动该进程的命令行
environ:所有与该进程有关的环境变量
status:进程状态
exe:该进程对应的可执行文件
cwd:current work directory
root:该进程的根目录,通常是/
fd:指向某进程打开文件的描述符
cpu:cpu占用时间
注意:如果某个进程访问/proc/self,实际上是访问它本身对应的proc目录。
4.通过proc文件系统,修改内核参数
proc文件系统下的大部分内容是read-only的,但是在/proc/sys下面的内容大部分是可写的。
$ cat /proc/sys/kernel/hostname
hyk-linux
root@hyk-linux:/home/hyk# echo "hyk-pc" > /proc/sys/kernel/hostname
$ cat /proc/sys/kernel/hostname
hyk-pc
5.通过程序提取proc中的信息
[cpp]
#include <stdio.h>
#include <string.h>
/* Returns the clock speed of the system’s CPU in MHz, as reported by
/proc/cpuinfo. On a multiprocessor machine, returns the speed of
the first CPU. On error returns zero. */
float get_cpu_clock_speed ()
{
FILE* fp;
char buffer[1024];
size_t bytes_read;
char* match;
float clock_speed;
/* Read the entire contents of /proc/cpuinfo into the buffer.
fp = fopen (“/proc/cpuinfo”, “r”);
bytes_read = fread (buffer, 1, sizeof (buffer), fp);
fclose (fp);
/* Bail if read failed or if buffer isn’t big enough. */
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
/* NUL-terminate the text. */
buffer[bytes_read] = ‘/0’;
/* Locate the line that starts with “cpu MHz”. */
match = strstr (buffer, “cpu MHz”);
if (match == NULL)
return 0;
/* Parse the line to extract the clock speed. */
sscanf (match, “cpu MHz : %f”, &clock_speed);
return clock_speed;
*/
}
int main ()
{
printf (“CPU clock speed: %4.0f MHz/n”, get_cpu_clock_speed ());
return 0;
}