ÔÚlinuxÖÐͨ¹ýprocÎļþϵͳ½øÐÐÓû§Ì¬ÓëÄÚºË̬µÄ½»»¥»òÄÚºË΢µ÷¶¼Ò»ÖֱȽϼòµ¥ÓÐЧµÄÊֶΣ¬
linux ¶ÁÈ¡procÎļþÖ®seqfiledzÎö
¡£×î½üÓÉÓÚÏîÄ¿ÐèÒª£¬ÐèҪͨ¹ýproc°ÑÒ»¸öÄÚºËÄ£¿éµÄÊý¾ÝÊä³öµ½Óû§Ì¬£¬½è´Ë»ú»áѧϰÁËÒ»ÏÂseq_file¡£ÔÚ´Ë×öÒ»¸ö¼òµ¥µÄ¼Ç¼£¬²»¶ÔµÄµØ·½»¶ÓÅúÆÀÖ¸Õý°¡¡£ÒªÓÃseq_file£¬ÐèÒª#includeºÃÀ²£¬·Ï»°²»¶à˵£¬¿ªÊ¼°É£¬^_^¡£¼ÙÉ裬ÔÚÎÒÃǵÄÒ»¸öÄÚºËÄ£¿éÖУ¬ÓÐÒ»×éÊý¾Ý´æ·ÅÔڿɵü´úµÄÊý¾Ý½á¹¹(È磬Á´±í¡¢Êý×éµÈ)ÖУ¬Ïë°ÑËüÃÇͨ¹ýprocÊä³öµ½Óû§Ì¬ÖУ¬Í¨¹ýcatµÈ·½Ê½½øÐв鿴£¬ÄǸÃÔõô×öÄØ¡£ÎªÁ˼òµ¥Æð¼û£¬¼ÙÉèÎÒÃÇÓÐÒ»¸öÁ´±íµÄÊý¾Ý£¬Á´±íµÄÍ·²¿Í¨¹ýÒ»¸öÃûΪlist_headµÄ±äÁ¿Ö¸Ïò£¬¸Ã½á¹¹Ìå±¾ÉíÓÃÒ»¸ö¶Áд×ÔÐýËø±£»¤¡£Á´±í½ÚµãµÄ½á¹¹¼òµ¥ÈçÏ£º
struct node{
struct node *next;
int num;
};
struct node* list_head;//Á´±íÍ·²¿
DEFINE_RWLOCK(list_lock);//¶¨Òå²¢³õʼ»¯Ò»¸ö¶Áд×ÔÐýËø¡£
seq_fileÖж¨ÒåÁËÒ»×éÓÃÓÚµü´úµÄº¯ÊýÖ¸Õ룬Æä¹¦ÄÜÀàËÆÓÚc++ÖеÄǰÏòµü´úÆ÷£¬µ«ÊǶàÁËÒ»¸öÃûΪshowµÄ³ÉÔ±£¬ÓÃÓÚÊä³ö½ÚµãµÄÐÅÏ¢¡£Õâ×麯ÊýÖ¸ÕëÉùÃ÷ÔÚÒ»¸öÃûΪstruct seq_operationsµÄ½á¹¹ÌåÖУ¬ÈçÏ£º
struct seq_operations {
void * (*start) (struct seq_file *m, loff_t *pos);
void (*stop) (struct seq_file *m, void *v);
void * (*next) (struct seq_file *m, void *v, loff_t *pos);
int (*show) (struct seq_file *m, void *v);
};
start¿ÉÒÔ×öһЩ×ÊÔ´»ñÈ¡ºÍ³õʼ»¯¹¤×÷£¬Ï൱c++µÄ¹¹Ô캯ÊýµÄ×÷Óã¬ËüµÄ·µ»ØÖµ»á×÷ΪµÚÒ»´Îµ÷ÓÃshowÓënextµÄµÚ¶þ¸ö²ÎÊý´«¸øËûÃÇ£¬Ö®ºóÿ´Î»áµ÷ÓÃnext£¬ºÍshow;startÈô·µ»ØNULLÔòÖ±½Óµ÷ÓÃstop²»»áÔÙÈ¥µ÷ÓÃshowºÍnext¡£ÈôÓÐһЩÎļþÍ·ÒªÊä³ö¿ÉÒÔ·µ»ØSEQ_START_TOKENÄÚºËÖÐËü±»¶¨ÒåΪ£º
#define SEQ_START_TOKEN ((void *)1)
nextµÄ·µ»ØÖµ»á×÷ΪshowºÍÏÂÒ»´Îµ÷ÓÃnextµÄµÚ¶þ¸ö²ÎÊý(¼´v)´«¸øËûÃÇ£¬µ±next·µ»ØNULLʱ£¬¾Íµ÷ÓÃstop¡£
stopµÄ×÷ÓÃÔòÀàËÆc++ÀàÖеÄÎö¹¹º¯ÊýµÄ×÷Ó㬸ºÔð×ÊÔ´µÄÇåÀíºÍ¹é»¹²Ù×÷¡£
showº¯ÊýÕýÈ··µ»Ø0£¬³ö´í·µ»ØÏàÓ¦µÄ³ö´íÂë¡£
×¢ÒâÓÉÓÚÊä³öµÄÐÅÏ¢´óÓÚÄÚºËÒ»´Î·ÖÅäµÄ»º³åÇøµÈÔÒò(¾ßÌåÔÒòµÈÏ´Îд¹ØÓÚseq_readµÈº¯ÊýµÄʵÏÖʱ¾ÍÔÚ˵Ã÷£¬µ½Ê±ºò¾Í±È½ÏÇå³þÁË)start£¬show£¬next £¬stop¿ÉÄÜ»áµ÷Óöà´Î£¬Õâ¾ÍÐèÒªstartºÍnextµÄµÚÈý¸ö²ÎÊýposÀ´Çø±ðËûÃÇ¡£ËùÒÔËüÃǵĵ÷ÓÃ˳Ðò´ó¸Å¿ÉÒÔÃèÊöÈçÏ£º start->show->next->show->next->show->...->next->stop¡£
×¢ÒâÒ²¿ÉÄÜÈçÏÂ(start stopµ÷Óöà´Î)£º start->show->next->show->next->show->...->next->stop->start->show->next...->next->stop¡£Õ⼸¸öµü´úº¯ÊýÔÚÎÒÃÇÀý×ÓÖпÉÒÔ¶¨ÒåÈçÏ£º
static void * my_start(struct seq_file*m, l loff_t *pos)
{
int i = 1;
struct node* tmp_entry;
read_lock_bh(list_lock);//»ñÈ¡¶Áд×ÔÐýËø
if(*pos==0){
return SEQ_START_TOKEN;
}
for(tmp_entry = list_head;tmp_entry != NULL; tmp_entry=tmp-entry->next){
if(i==*pos)
return tmp_entry;
++i;
}
return NULL;
}
static void my_stop (struct seq_file *m, void *v)
{
read_unlock_bh(tmp_lock);//ÊÍ·Å×ÔÐýËø
seq_printf(m,"\n\n-------------data information end---------------------------");
}
static void * my_next(struct seq_file *m, void *v, loff_t *pos)
{
++*pos;
return (SEQ_START_TOKEN==v)?list_head:((struct node*)v)->next;
}
static int my_show(struct seq_file *m, void *v)
{
struct node* tmp_entry;
static int line_count= 0;
if(SEQ_START_TOKEN==v){
seq_printf(m,"\n\n-------------data informations start---------------------------\n\n");
}else{
tmp_entry = (struct node*)v;
seq_file(m," %d ",tmp_entry->num);
if(++line_count==10){//Ò»ÐÐÊä³öÊ®¸öÊý¾Ý
seq_printf(m,"\n");
line_count=0;
}
}
return 0;
}
È»ºó£¬¶¨ÒåÒ»¸östruct seq_operations£¬ÈçÏ£º
static const struct seq_operations my_seq_ops={
.start = my_start,
.next = my_next,
.stop = my_stop,
.show = my_show,
};
µ½Õ⣬ÎÒÃÇ»¹Òª¶¨ÒåÒ»¸öº¯Êý°Ñmy_seq_opsµÄµØÖ·³ö¸øÄںˣ¬ÈçÏ£¬
static int proc_my_test_open((struct inode *inode, struct file *file)
{
return seq_open(file,&my_seq_ops);
}
×îºóÔÙ¶¨ÒåÒ»¸östruct file_operations½á¹¹Ì壬ÎÒÃǵÄproc_my_test_open´«¸øÄںˣ¬²¢µ÷ÓÃproc_create,´´½¨Ò»¸öprocĿ¼¾Í´ó¹¦¸æ³ÉÀ²£¬
µçÄÔ×ÊÁÏ
¡¶linux ¶ÁÈ¡procÎļþÖ®seqfiledzÎö¡·(https://www.unjs.com)¡£´úÂëÈçÏ£ºstatic const struct file_operations my_file_ops={
.owner = THIS_MODULE,
.open = proc_my_test_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
my_file_opsproc_create("my_test", 0, NULL, &my_file_ops);
Æäʵ¶ÔÓÚ¼òµ¥µÄÊä³ö£¬¿ÉÒÔ¼òµ¥¶¨ÒåÒ»¸öshowº¯ÊýÈ»ºóͨ¹ýsingle_open¶ø·ÇÎÒÃÇÕâÀïµÄseq_open£¬Õâ¸ö·½·¨±È½Ï¼òµ¥£¬¾ßÌå°ì·¨¿ÉÒÔ×ÔÐÐgoogle¡£