list_head使用

原创 2015年11月19日 10:26:33

list_head在内核中的实现:

list.h文件源码

#ifndef _LIST_H
#define _LIST_H

#define _INLINE_ static inline

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

#define LIST_HEAD_INIT(name) {&(name), &(name)} 

//定义并初始化头结点head
#define LIST_HEAD(name)\
    struct list_head name = LIST_HEAD_INIT(name)

//初始化头结点ptr,因此需要首先定义ptr
#define INIT_LIST_HEAD(ptr)do{\
    (ptr)->next = (ptr);\
	(ptr)->prev = (ptr);\
}while (0)

_INLINE_ void __list_add(struct list_head *add,
        struct list_head *prev,
        struct list_head *next)
{
    next->prev = add;
    add->next = next;
    add->prev = prev;
    prev->next = add;
}

_INLINE_ void list_add(struct list_head *add, struct list_head *head)//每次添加节点到head之后,始终都是添加到头结点之后
{
    __list_add(add, head, head->next);
}

_INLINE_ void list_add_tail(struct list_head *add, struct list_head *head)//每次添加节点都是头结点之前,由于是循环链表,就是说添加到链表尾部
{
    __list_add(add, head->prev, head);
}

_INLINE_ void __list_del(struct list_head *prev, struct list_head *next)
{
    next->prev = prev;
    prev->next = next;
}

_INLINE_ void list_del(struct list_head *entry)//删除节点
{
    __list_del(entry->prev, entry->next);
}

_INLINE_ void list_del_init(struct list_head *entry)
//删除节点,并初始化被删除的结点(也就是使被删除的结点的prev和next都指向自己)
{
    __list_del(entry->prev, entry->next);
    INIT_LIST_HEAD(entry);
}

_INLINE_ int list_empty(struct list_head *head)//判断链表是否为空
{
    return head->next == head;
}

_INLINE_ void list_splice(struct list_head *list, struct list_head *head)
//通过两个链表的head,进行连接
{
    struct list_head *first = list->next;

    if (first != list) {
        struct list_head *last = list->prev;
        struct list_head *at = head->next;

        first->prev = head;
        head->next = first;

        last->next = at;
        at->prev = last;
    }
}

#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
                                  
//遍历链表,此时删除节点的操作可能会出错
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next) //新代码中出现prefetch() 可以不考虑,用于预取以提高遍历速度

//遍历链表,可以同时有删除节点的操作
#define list_for_each_safe(pos, pnext, head) \
    for (pos = (head)->next, pnext = pos->next; pos != (head); \
            pos = pnext, pnext = pos->next)

#undef _INLINE_
#endif

使用实例:

use_list.c文件

#include"list.h"
#include<stdio.h>
#include<stdlib.h>

typedef struct node{
    int data;
    struct list_head list;
}node;

void main(){
    struct list_head ll, *plist;
    struct node *n;
    INIT_LIST_HEAD(&ll);

    for(int i=0; i<5; i++){
	n=(struct node *)malloc(sizeof(struct node));
        n->data=i;
	list_add_tail(&n->list, &ll);
    }

	list_for_each(plist, &ll){
		struct node *pnode=list_entry(plist, struct node, list);
		printf("data=%d\n", pnode->data);
	}
	
	if(!list_empty(&ll)){
		struct list_head *ptr=ll.next;
		list_del_init(ptr);
		n=list_entry(ptr, struct node, list);
		printf("n->data=%d\n", n->data);
	}

	printf("after remove the first node\n");	
	list_for_each(plist, &ll){
		struct node *pnode=list_entry(plist, struct node, list);
		printf("data=%d\n", pnode->data);
	}
	
	printf("list's offset=%d\n", (unsigned long)(&((struct node *)0)->list));
}

执行结果:

data=0
data=1
data=2
data=3
data=4
n->data=0
after remove the first node
data=1
data=2
data=3
data=4




相关文章推荐

linux下一个计时器的实现(使用了list_head)

c文件=====================================================关于list_head请看另一篇文章http://blog.csdn.net/lvhon...

typeof详解及Linux 中list_head 如何使用

#include #include #include #include #include #include MODULE_LICENSE("Dual BSD/GPL"); struct g...
  • ychongx
  • ychongx
  • 2014年06月15日 20:55
  • 744

linux kernal中list_head的移植和使用

在Linux内核中使用了大量的链表结构来组织数据,包括设备列表以及各种功能模块中的数据组织。这些链表大多采用在[include/linux/list.h]实现的一个相当精彩的链表数据结构。 /** @...

linux内核中list_head使用介绍

list_head结构的介绍 list_head结构定义在 struct list_head { struct list_head *next, *prev; }; 有的人可能看到这...

20150203 【 内核链表 kernel_list.h 】 list_head 使用

内核链表模板【全部在头文件实现,我是第一次看到这种形式】 #ifndef __DLIST_H #define __DLIST_H /* This file is from Linu...

linux 内核分析之链表解析(list_head)

一、 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指针将一系列数据节点连接成一条数据链,是线性表的一种重要实现方式。相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总...
  • sonbai
  • sonbai
  • 2013年03月04日 20:15
  • 828

list_head链表源码

  • 2015年02月12日 14:30
  • 5KB
  • 下载

list_head 源码

  • 2013年05月04日 01:15
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:list_head使用
举报原因:
原因补充:

(最多只允许输入30个字)