Linux内核中链表的使用

发表于:2012-8-08 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:rosetta    来源:51Testing软件测试网采编

  3、在链表中增加一个节点

static inline void list_add(struct list_head *new, struct list_head *head)
    {  
        __list_add(new, head, head->next);
    }

  要调用此函数,只要在上一步后面接上:

list_add(&ist->list, &addr_list);

  完整的增加操作:

struct ipstore *ist;
    ist = kmalloc(sizeof (*ist), GFP_ATOMIC);
    if(!ist)
    {
        printk("kmalloc failed.\n");
        return -1;
    }
   
    ist->time = jiffies+time*HZ;
    ist->addr[0] = 0xc0a80101;//IP:192.168.1.1
    INIT_LIST_HEAD(&ist->list);
    list_add(&ist->list, &addr_list);

  这样在链表addr_list中就增加了新的链表节点。

  4、遍历链表

  为什么不先讲删除节点,因为很多情况下都是先遍历链表,找到匹配的节点后再去删除的,所以先讲遍历链表,遍历链表分普通遍历和安全删除遍历,可见如果要删除链表结点我们就需要使用安全删除遍历。

  普通遍历,主要使用在当加入节点时判断是否有相同的结点存在,如果已存在就不需要再往下操作了,如下判断是否有相同的IP地址存在。

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

    struct list_head *p;
    struct ipstore *store;
    list_for_each(p, &addr_list)
    {
      store = list_entry(p, struct ipstore, list);
      if(store->addr[0] == ist->addr[0])
      {
          if(ist)
              kfree(ist);
          break;
      }
    }
    INIT_LIST_HEAD(&ist->list);
    list_add(&ist->list, &addr_list);

  ist就是上一步的链表结点指针,如果链表中有IP和新增节点IP地址相同的节点则释放刚分配的新节点空间,不进行任何操作,否则加入addr_list链表中。

  内核提供了一个比较简单的接口,可以在遍历的同时取出节点,此函数内部封装了list_entry():

#define list_for_each_entry(pos, head, member)              \
    for (pos = list_entry((head)->next, typeof(*pos), member);  \
         prefetch(pos->member.next), &pos->member != (head);    \
         pos = list_entry(pos->member.next, typeof(*pos), member))

32/3<123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号