LINUX鏈表學習

      使用前需要初始化,內核鏈表的結構是個雙向循環鏈表,只有指針域,數據域根據使用鏈表的人的具體需求而定。

        兩種初始化方法

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章