Linux2.6.38.2进程列表显示


这里使用/proc文件系统显示出进程列表。/proc文件系统是一种特殊的,由软件创建的文件系统,内核使用它向外界导出信息。/proc下的每个文件都绑定于一个内核函数,用户读取其中的文件时,该函数动态的生成文件的”内容”。现代Linux发行版中的很多工具都是通过/proc/来获取它们需要的信息,例如ps,top和uptime。/proc存于内存中,关机后就消失了。

所有使用/proc的模块必须包含<linux/proc_fs.h>,并通过这个头文件来定义正确的函数。为创建一个只读的/proc文件,驱动必须实现一个函数,用于读取文件时生成数据。当某个进程读取这个文件时,读取请求会通过这个函数发送到驱动程序模块。在某个进程读取我们的/proc文件时,内核会分配一个内存页(PAGE_SIZE字节的内存块),驱动程序可以将数据通过这个内存页返回到用户空间。该缓冲区会传入传入我们定义的函数,而该函数称为read_proc方法:

  1. int (*read_proc)(char *page, char **start, off_t off, int count, int *eof, void *data);  

一旦创建好了一个read_proc函数,就需要把它与一个/proc入口项连接起来。这通过调用create_proc_read_entry实现:

  1. struct proc_dir_entry *create_proc_read_entry(const char *name,    
  2.                 mode_t mode, struct proc_dir_entry *base,   
  3.                 read_proc_t *read_proc, void *data);  

其中,name是要创建的文件名称;mode是该文件的保护掩码,base是该文件所在的目录,read_proc是实现文件的read_proc函数,内核会忽略data参数,但是会将该函数传递给read_proc。
    在卸载模块时,/proc中的入口项也应被删除。remove_proc_entry就是用来撤销create_proc_read_entry所做的工作的:

  1. remove_proc_entry("myproc",NULL); /*parent dir*/  

在read_myproc中,我们打印进程列表的信息。这里我是通过手动遍历的,没有使用list_for_each函数。在内核中进程是使用进程描述符task_struct来描述的,它是一个结构体,包含了进程的相关信息。这个结构体的获得是通过slab来分配的。正因为如此,所以UNIX有一个特性就是创建进程非常迅速。task_struct是通过list_head域链接到一起的,这个双向循环链表把所有的进程描述符串到了一起。在linux内核链表中,不是链表结构中包含数据,而是在数据结构中包含链表节点。init_task是0号进程的进程描述符(也就是传说中的idle或swapper进程)。从它下一个开始遍历,也就是从init进程开始。list_entry可以通过指向成员的指针获得指向这个容器的指针。

  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3. #include <linux/proc_fs.h>  
  4. #include <linux/list.h>  
  5. #include <linux/types.h>  
  6. #include <linux/sched.h>   
  7.   
  8. int read_myproc(char *page, char **start, off_t off, int count, int *eof, void *data){   
  9.     struct task_struct *p;   
  10.     printk("%15s %15s %15s\n""PID""STAT""COMMAND");   
  11.     for(p = list_entry(init_task.tasks.next,struct task_struct, tasks);p!=&init_task;){   
  12.         printk("%15d %15ld %15s\n", p->pid, p->state, p->comm);   
  13.         p = list_entry(p->tasks.next, struct task_struct, tasks);   
  14.     }   
  15.     return 0;   
  16. }   
  17.   
  18. static int __init myproc_init(void){   
  19.     struct proc_dir_entry * e = create_proc_read_entry("myproc",0,NULL,read_myproc,NULL);   
  20.     e->read_proc = read_myproc;   
  21.     return 0;    
  22. }   
  23.   
  24. static void __exit myproc_exit(void){   
  25.     removre_proc_entry("myproc",NULL);   
  26. }   
  27.   
  28. module_init(myproc_init);   
  29. module_exit(myproc_exit);   
  30. MODULE_LICENSE("GPL");   
  31. MODULE_AUTHOR("liwanpeng");  

显示结果如下,我只截了部分:


相关内容