linux list_head结构体

欢迎访问小站,阅读原文http://www.yandong.org/archives/495

简介

list_head是linux
kernel中非常重要的一个结构体,是双向链表的数据结构体,为了减少浪费,众多链表都是用list_head以及其相关原语操作,比如所有的进程是靠它串联在一起的,所有的inode也靠它串联在一起等等。

 

定义:

struct list_head { struct list_head *next, *prev; }

特别注意的是,list_head中的指针存放的是另一个list_head的地址,而不是含有list_head结构的整个数据结构的地址,如下图。


如何连接

1025550 

处理函数和宏

1. list_entry: container_of功能相同; /**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 */ #define list_entry(ptr, type, member) \
    container_of(ptr, type, member) 2. list_for_each:向后(next)遍历head所指链表每个节点 /**
 * list_for_each    -    iterate over a list
 * @pos:    the &struct list_head to use as a loop cursor.
 * @head:    the head for your list.
 */ #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) 3. list_for_each_prev:向前(prev)遍历head所指链表每个节点 /**
     * list_for_each_prev - iterate over a list backwards
     * @pos: the &struct list_head to use as a loop cursor.
     * @head: the head for your list.
     */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; pos != (head); pos = pos->prev) 4. list_for_each_entry /**
 * list_for_each_entry    -    iterate over list of given type
 * @pos:    the type * to use as a loop cursor.
 * @head:    the head for your list.
 * @member:    the name of the list_struct within the struct.
 */ #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \
     pos = list_entry(pos->member.next, typeof(*pos), member))

实例

(1)遍历所有进程

Struct task_struct *p; for_each_process(p) {     printk(KERN_ERR "pid is %d\n", p->pid);     printk(KERN_ERR "comm is %s\n", p->comm); }

 

其中for_each_process(p)的定义如下,

#define for_each_process(p) \ for(p=&init_task; ( p=list_entry( (p)->tasks.next, \ struct task_struct, tasks ) )!=&init_task; )

init_task是全局符号,代表init进程(即1号进程),在system.map文件中可以看到init_task进程的地址

tasks 是进程结构体task_struct中的元素,定义为 struct
list_head tasks

(2)遍历得到进程的所有子进程

static int my_child(struct task_struct * p,int num) { struct task_struct * task; struct list_head *list; list_for_each(list,&p->children) { task = list_entry(list,struct task_struct,sibling); printk(KERN_ERR "--%s[%d %x]", task->comm,task->pid, task); } return 1; }


(3)根据进程中的inode遍历系统中所有的inode

struct inode * inode_ptr=p->fs->pwd.dentry->d_inode; for(;( inode_ptr=list_entry(inode_ptr->i_list.next, \ struct inode, i_list) )!= \ (p->fs->pwd.dentry->d_inode);) { ... }

转载于:https://my.oschina.net/toyandong/blog/123609

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值