首页 > 系统相关 >编写模块遍历系统中的进程(续)

编写模块遍历系统中的进程(续)

时间:2023-01-29 16:33:13浏览次数:34  
标签:tmp 遍历 int void list 模块 each 编写 data


上一次写了一个简单的通过模块 遍历进程链表。代码比较粗糙,而且每次需要用不同的方法进行遍历时需要修改源代码,这样很不方便。今天把这个重新修改了一下,增加了下面几个功能:


1.通过模块参数选择使用那个方法进行遍 历


2.可以将测试的结果写入文件




trave_process.c


​​/*****************************************
*功能:利用进程链表遍历当前系统中的所有进程
*同时可以打印出进程的相关信息
*此程序可以将比较信息输出到指定的文件中
*
*author:孟阿龙(XiyouLinux)​​
​​ *url:http://boyan.cublog.cn
* ***************************************/
# include < linux/ module. h>
# include < linux/ init. h>
# include < linux/ list . h>
# include < linux/ sched. h>
# include < linux/ time . h>
# include < linux/ fs. h>
# include < asm / uaccess. h>
# include < linux/ mm. h>


MODULE_AUTHOR( "Along" ) ;
MODULE_LICENSE( "GPL" ) ;

struct task_struct * task = NULL , * p = NULL ;
struct list_head * pos = NULL ;
struct timeval start, end;
int count = 0;

/*function_use表示使用哪一种方法测试,
* 0:三个方法同时使用,
* 1:list_for_each,
* 2:list_for_each_entry,
* 3:for_each_process
*/
int function_use = 0;
char * method;
char * filename= "testlog" ;

void print_message( void ) ;
void writefile( char * filename, char * data ) ;
void traversal_list_for_each( void ) ;
void traversal_list_for_each_entry( void ) ;
void traversal_for_each_process( void ) ;


static int init_module_list( void )
{
switch ( function_use) {
case 1:
traversal_list_for_each( ) ;
break ;
case 2:
traversal_list_for_each_entry( ) ;
break ;
case 3:
traversal_for_each_process( ) ;
break ;
default :
traversal_list_for_each( ) ;
traversal_list_for_each_entry( ) ;
traversal_for_each_process( ) ;
break ;
}
return 0;
}
static void exit_module_list( void )
{
printk( KERN_ALERT "GOOD BYE!!/n" ) ;
}

module_init( init_module_list ) ;
module_exit( exit_module_list ) ;
module_param( function_use, int , S_IRUGO) ;

void print_message( void )
{
char * str1 = "the method is: " ;
char * str2 = "系统当前共 " ;
char * str3 = " 个进程/n" ;
char * str4 = "开始时间: " ;
char * str5 = "/n结束时间: " ;
char * str6 = "/n时间间隔: " ;
char * str7 = "." ;
char * str8 = "ms" ;
char data[ 1024] ;
char tmp[ 50] ;
int cost;

printk( "系统当前共 %d 个进程!!/n" , count ) ;
printk( "the method is : %s/n" , method) ;
printk( "开始时间:%10i.%06i/n" , ( int ) start. tv_sec, ( int ) start. tv_usec) ;
printk( "结束时间:%10i.%06i/n" , ( int ) end. tv_sec, ( int ) end. tv_usec) ;
printk( "时间间隔:%10i/n" , ( int ) end. tv_usec- ( int ) start. tv_usec) ;

memset ( data, 0, sizeof ( data) ) ;
memset ( tmp, 0, sizeof ( tmp) ) ;

strcat ( data, str1) ;
strcat ( data, method) ;
strcat ( data, str2) ;
snprintf( tmp, sizeof ( count ) , "%d" , count ) ;
strcat ( data, tmp) ;
strcat ( data, str3) ;
strcat ( data, str4) ;


memset ( tmp, 0, sizeof ( tmp) ) ;
/*
* 下面这种转换秒的方法是错误的,因为sizeof最终得到的长度实际是Int类型的
* 长度,而实际的妙数有10位数字,所以最终存到tmp中的字符串也就只有三位
* 数字
* snprintf(tmp, sizeof((int)start.tv_sec),"%d",(int)start.tv_usec );
*/

/*取得开始时间的秒数和毫秒数*/

snprintf( tmp, 10, "%d" , ( int ) start. tv_sec ) ;
strcat ( data, tmp) ;
snprintf( tmp, sizeof ( str7) , "%s" , str7 ) ;
strcat ( data, tmp) ;
snprintf( tmp, 6, "%d" , ( int ) start. tv_usec ) ;
strcat ( data, tmp) ;

strcat ( data, str5) ;

/*取得结束时间的秒数和毫秒数*/

snprintf( tmp, 10, "%d" , ( int ) end. tv_sec ) ;
strcat ( data, tmp) ;
snprintf( tmp, sizeof ( str7) , "%s" , str7 ) ;
strcat ( data, tmp) ;
snprintf( tmp, 6, "%d" , ( int ) end. tv_usec ) ;
strcat ( data, tmp) ;

/*计算时间差,因为可以知道我们这个程序花费的时间是在
*毫秒级别的,所以计算时间差时我们就没有考虑秒,只是
*计算毫秒的差值
*/
strcat ( data, str6) ;
cost = ( int ) end. tv_usec- ( int ) start. tv_usec;
snprintf( tmp, sizeof ( cost) , "%d" , cost ) ;

strcat ( data, tmp) ;
strcat ( data, str8) ;
strcat ( data, "/n/n" ) ;

writefile( filename, data) ;
printk( "%d/n" , sizeof ( data) ) ;


}
void writefile( char * filename, char * data )
{
struct file * filp;
mm_segment_t fs;

filp = filp_open( filename, O_RDWR| O_APPEND| O_CREAT, 0644) ; ;
if ( IS_ERR( filp) ) {
printk( "open file error.../n" ) ;
return ;
}
fs = get_fs( ) ;
set_fs( KERNEL_DS) ;
filp- > f_op- > write ( filp, data, strlen ( data) , & filp- > f_pos) ;
set_fs( fs) ;
filp_close( filp, NULL ) ;
}
void traversal_list_for_each( void )
{

task = & init_task;
count = 0;
method= "list_for_each/n" ;

do_gettimeofday( & start) ;
list_for_each( pos, & task- > tasks ) {
p = list_entry( pos, struct task_struct, tasks ) ;
count + + ;
printk( KERN_ALERT "%d/t%s/n" , p- > pid, p- > comm ) ;
}
do_gettimeofday( & end) ;

print_message( ) ;

}

void traversal_list_for_each_entry( void )
{

task = & init_task;
count = 0;
method= "list_for_each_entry/n" ;

do_gettimeofday( & start) ;
list_for_each_entry( p, & task- > tasks, tasks ) {
count + + ;
printk( KERN_ALERT "%d/t%s/n" , p- > pid, p- > comm ) ;
}
do_gettimeofday( & end) ;

print_message( ) ;
}

void traversal_for_each_process( void )
{
count = 0;
method= "for_each_process/n" ;

do_gettimeofday( & start) ;
for_each_process( task) {
count + + ;
printk( KERN_ALERT "%d/t%s/n" , task- > pid, task- > comm ) ;
}
do_gettimeofday( & end) ;

print_message( ) ;
}

 


Makefile:




​​obj- m : = trave_process. o
KERNELDIR ? = / lib/ modules/ $ ( shell uname - r) / build
PWD : = $ ( shell pwd)
all:
make - C $ ( KERNELDIR) M= $ ( PWD) modules
clean:
make - C $ ( KERNELDIR) M= $ ( PWD) clean
rm - fr * . markers * . order

 


测试方法:


insmod trave_process.ko             /*选择同时使用三种方法进行遍历*/


insmod trave_process.ko function_use=1        /*选择使用list_for_each*/


insmod trave_process.ko function_use=2         /*选择使用list_for_each_entry*/


insmod trave_process.ko function_use=3         /*选择使用for_each_process*/



模 块加载完成之后,会在当前模块所在目录下生成相应的测试报告 testlog。



​​along@along- laptop: ~ / code/ modules/ list_process_tofile$ cat testlog 
the method is: list_for_each
系统当前共 160 个进程
开始时间: 127009604. 25840
结束时间: 127009604. 25892
时间间隔: 520ms

the method is: list_for_each_entry
系统当前共 160 个进程
开始时间: 127009604. 25906
结束时间: 127009604. 25956
时间间隔: 499ms

the method is: for_each_process
系统当前共 160 个进程
开始时间: 127009604. 25962
结束时间: 127009604. 26011
时间间隔: 497ms


   这个程序现在主要问题就是写文件这块比较麻烦,我对文件读写这块不了解,等弄清了文件读写这部分之后再继续改进。

标签:tmp,遍历,int,void,list,模块,each,编写,data
From: https://blog.51cto.com/tody/6025866

相关文章