使用前需要初始化,內核鏈表的結構是個雙向循環鏈表,只有指針域,數據域根據使用鏈表的人的具體需求而定。
兩種初始化方法
struct list_head { struct list_head *next, *prev;};
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
#define LIST_HEAD_INIT(name) { &(name), &(name) }
定義一個鏈表
struct list_head RTPbuf_head;
然後初始化。
第一種:INIT_LIST_HEAD(&RTPbuf_head);
這個是調用函數,讓其頭尾指向一個地址。
第二種:struct list_head RTPbuf_head = LIST_HEAD_INIT(RTPbuf_head);
展開後就是:
struct list_head RTPbuf_head = {&(RTPbuf_head),&(RTPbuf_head)};
就是初始化結構體。list頭指向尾。雙向鏈表
添加鏈表成員兩種方法
1.
static HPT_INLINE void list_add(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head, head->next);
}
static HPT_INLINE void __list_add(struct list_head * _new, struct list_head * prev, struct list_head * next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
list_add函數,可以在鏈中增加節點,該函數爲頭插法,即每次插入的節點都位於上一個節點之前,
比如上一個節點是head->1->next,本次使用頭插法插入之後,鏈表結構變成了 head->2->1->next。
這種就是先進後出。
2.
static HPT_INLINE void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
該函數向尾部添加。prev-->>head prev-->1-->head prev-->1-->2-->head
這種是先進先出模式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "include/linux/list.h"
struct list_head RTPbuf_head;
typedef struct _rtpbuf
{
int len;
char * buf;
struct list_head list;
}RTPbuf_s;
int main(int argc,char **argv)
{
int i=0;
RTPbuf_s *p;
INIT_LIST_HEAD(&RTPbuf_head);
for(i=0;i<10;i++)
{
p= (RTPbuf_s *)malloc(sizeof(RTPbuf_s));
p->buf = (char *)malloc(10+i);
p->len=10+i;
memset(p->buf,10+i,p->len);
list_add_tail(&(p->list),&RTPbuf_head);
}
while(1)
{
/***********************************************************************
static HPT_INLINE int list_empty(struct list_head *head)
{
return head->next == head;
}
頭等於尾說明鏈表爲空。
************************************************************************/
if(!list_empty(&RTPbuf_head))
{
/***************************************************************************
#define get_first_item(attached, type, member) \
((type *)((char *)((attached)->next)-(HPT_UPTR)(&((type *)0)->member)))
由結構體成員list地址找到該結構體的地址
***************************************************************************/
p=get_first_item(&RTPbuf_head,RTPbuf_s,list);
for(i=0;i<p->len;i++)
{
printf("%d-",p->buf[i]);
}
printf("\n");
list_del(&(p->list));
free(p->buf);
free(p);
p = NULL;
}
else
{
break;
}
sleep(1);
}
return 0;
}