list_for_each 详解

list_for_each 详解

最近在学习linux内核,看到进程管理时,有这么一段代码,一脸懵逼;

struct task_struct *task; 
struct list_head *list;
list_for_each(list, &current->children) { 
    task = list_entry(list, struct task_struct, sibling); /* task 现在指向某个子进程 */ } 

其中task即为某个子进程的地址

于是求助大百度,现做些总结:
offsetof

//offsetof(/include/linux/stddef.h):相关宏在内核中的地址
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

为清楚了解list_for_each的含义,先从offsetof开始讲起,offsetof表示MEMBER类型在TYPE类型中的偏移位置;该宏写的很巧妙,将0地址强转为TYPE类型,在对其中的MEMBER进行取址,将该地址转为size_t类型就获得了MEMBER类型在TYPE类型中的偏移位置。
container_of

//container_of(include/linux/kernel.h): 
#define container_of(ptr, type, member) ({ \ 
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 
    (type *)( (char *)__mptr - offsetof(type,member) );})

typeof表示取对应参数的类型;
container_of的作用表示先求出结构体成员(即member)在结构体(即type)中的偏移量,然后再根据member的地址(即ptr)来求出其所在结构体的地址。
list_for_each

#define list_for_each(pos, head) \
 for (pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next)

表示遍历循环链表,起始值是pos = (head)->next,条件是pos != (head),条件不满足时遍历下一个值pos = pos->next

#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

list_entry就表示ptr所在的结构体的地址,就是指针;

list_for_each(list, &current->children) { 
    task = list_entry(list, struct task_struct, sibling); /* task 现在指向某个子进程 */ } 

因此上面代码的含义就是依次访问当前线程的所有子线程;
prefetch()的作用
有一个共识是:程序访问的变量如果都能在系统内存cache中则能提升性能,prefetch是内核中一个预热内存函数,这样下次遍历时就能高效命中内存cache,从而提升程序性能。上面的代码中遍历链表时下次访问的内存为pos->next,故在每次遍历时对pos->next进行预热,从而提升性能。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nla_for_each_nested()是一个用于遍历嵌套属性的循环。该函数用于在netlink消息的属性层次结构中迭代,以便对嵌套属性进操作。它可以嵌套多个层级,并在每个层级上执指定的操作。 在这个循环中,我们可以使用nla_nest_start()和nla_nest_end()函数来开始和结束嵌套属性。 nla_nest_start()函数用于开始一个新的嵌套属性,而nla_nest_end()函数用于结束当前的嵌套属性。这些函数可以确保属性在层次结构中正确地嵌套。 这个循环的目的是遍历消息中的所有嵌套属性,并对它们进特定的操作,比如读取属性的值或修改属性的值。通过使用nla_for_each_nested()循环,我们可以轻松地处理复杂的属性层次结构,而不需要手动编写递归代码。 总结来说,nla_for_each_nested()是一个用于遍历嵌套属性的循环,可以在netlink消息的属性层次结构中迭代,并使用nla_nest_start()和nla_nest_end()函数来管理嵌套属性的开始和结束。这使得处理复杂的属性层次结构变得更加简单和高效。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [linux中通用Netlink详解及使用剖析(附源码)](https://blog.csdn.net/weixin_33744854/article/details/89723480)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值