TAILQ队列

常用的TAILQ的操作如下:
   宏名称                                   操作
   TAILQ_INIT                          初始化队列
   TAILQ_FOREACH                 对队列进行遍历操作
   TAILQ_INSERT_BEFORE    在指定元素之前插入元素
   TAILQ_INSERT_TAIL            在队列尾部插入元素
   TAILQ_EMPTY                      检查队列是否为空
   TAILQ_REMOVE                  从队列中移除元素

由于无法上传图片,在看代码之前,可以对照着http://blog.youkuaiyun.com/chen98765432101/article/details/56511598中的图来看,更加直观。

源码分析:
  #define TAILQ_HEAD(name, type)              /   
struct name {                       /   
struct type *tqh_first; /* 第一个元素的地址 */ /   
struct type **tqh_last; /* 最后一个元素的tqe_next地址*//   

 
  #define TAILQ_HEAD_INITIALIZER(head)      / 
  {NULL, &(head).tqh_first }
  
  #define TAILQ_INIT(head) do {               /   
(head)->tqh_first = NULL;                /   
(head)->tqh_last = &(head)->tqh_first;        /   
  } while (0) 
    TAILQ_HEAD_INITIALIZER与TAILQ_INIT作用基本一模一样,不过表现的形式不一样。

   应用:static TAILQ_HEAD(tailq_list, tailq_entry) g_tailqlist = TAILQ_HEAD_INITIALIZER(g_tailqlist);
   相当于首先新建一个类型为tailq_list的结构体g_tailqlist。
struct tailq_list {                        
struct tailq_entry *tqh_first;   
struct tailq_entry **tqh_last;  

   然后初始化这个结构体为:
g_tailqlist.tqh_first = NULL
g_tailqlist.tqh_last = &(g_tailqlist).tqh_first
  
  #define TAILQ_ENTRY(type)                   /   
  struct {                            /   
struct type *tqe_next;  /* 下一个元素的地址 */      /   
struct type **tqe_prev;/* 上一个元素的tqe_next的地址*/ /   
  }
      应用:主要存放下一个对象和前一个对象的指针。一般作为结构体中的字段。如上例中,结构体tailq_entry中就需要一个这样的结构:
          struct tailq_entry {
...
TAILQ_ENTRY(tailq_entry) tailq;
  };
      从而在TAILQ_INSERT_TAIL等操作函数中作为元素出现。   
   
  #define TAILQ_INSERT_TAIL(head, elm, field) do {        /   
(elm)->field.tqe_next = NULL;            /   
(elm)->field.tqe_prev = (head)->tqh_last;     /   
*(head)->tqh_last = (elm);               /   
(head)->tqh_last = &(elm)->field.tqe_next;        /   
  } while (0)
       应用:
   struct tailq_entry *subsystem;
   TAILQ_INSERT_TAIL(&g_tailqlist, subsystem, tailq);
   上述语句可以简单的看成是将subsystem插入到g_tailqlist列表的尾端。
   实际上执行的是:
         subsystem->tailq.tqe_next = NULL;            /   
subsystem->tailq.tqe_prev = g_tailqlist->tqh_last;(g_tailqlist->tqh_last是列表的最后一个元素(对于subsystem来说,即将成为它的上一个元素)的tqe_next地址。这个等式表示subsystem->tailq.tqe_prev指向的是上一个元素的tqe_next的地址)     /   
*g_tailqlist->tqh_last = subsystem; (这句话表示列表的最后一个元素是subsystem)              /   
g_tailqlist->tqh_last = &subsystem->tailq.tqe_next;(g_tailqlist->tqh_last指向列表的最后一个元素的tqe_next地址)
    
  
  #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {       /   
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    /   
  (elm)->field.tqe_next = (listelm);           /   
  *(listelm)->field.tqe_prev = (elm);          /   
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   /   
  } while (0)   
  作用:将elm插入到listelm的前面
  
  #define TAILQ_FIRST(head)       ((head)->tqh_first)   
  
  #define TAILQ_NEXT(elm, field)      ((elm)->field.tqe_next)   
 
  #define TAILQ_EMPTY(head)                       \  
    (TAILQ_FIRST(head) == TAILQ_END(head))

  #define TAILQ_FOREACH(var, head, field)                 \  
    for((var) = TAILQ_FIRST(head);                  \  
        (var) != TAILQ_END(head);                   \  
        (var) = TAILQ_NEXT(var, field))  

参考:http://blog.youkuaiyun.com/chen98765432101/article/details/56511598

源码分析:
  #define TAILQ_HEAD(name, type)              /   
struct name {                       /   
struct type *tqh_first; /* 第一个元素的地址 */ /   
struct type **tqh_last; /* 最后一个元素的tqe_next地址*//   

 
  #define TAILQ_HEAD_INITIALIZER(head)      / 
  {NULL, &(head).tqh_first }
  
  #define TAILQ_INIT(head) do {               /   
(head)->tqh_first = NULL;                /   
(head)->tqh_last = &(head)->tqh_first;        /   
  } while (0) 
    TAILQ_HEAD_INITIALIZER与TAILQ_INIT在我看来作用一模一样,不过表现的形式不一样。
   应用:static TAILQ_HEAD(tailq_list, tailq_entry) g_tailqlist = TAILQ_HEAD_INITIALIZER(g_tailqlist);
   相当于首先新建一个类型为tailq_list的结构体g_tailqlist。
struct tailq_list {                        
struct tailq_entry *tqh_first;   
struct tailq_entry **tqh_last;  

   然后初始化这个结构体为:
g_tailqlist.tqh_first = NULL
g_tailqlist.tqh_last = &(g_tailqlist).tqh_first
  
  #define TAILQ_ENTRY(type)                   /   
  struct {                            /   
struct type *tqe_next;  /* 下一个元素的地址 */      /   
struct type **tqe_prev;/* 上一个元素的tqe_next的地址*/ /   
  }
      应用:主要存放下一个对象和前一个对象的指针。一般作为结构体中的字段。如上例中,结构体tailq_entry中就需要一个这样的结构:
          struct tailq_entry {
...
TAILQ_ENTRY(tailq_entry) tailq;
          };
      从而在TAILQ_INSERT_TAIL等操作函数中作为元素出现。   
   
  #define TAILQ_INSERT_TAIL(head, elm, field) do {        /   
(elm)->field.tqe_next = NULL;            /   
(elm)->field.tqe_prev = (head)->tqh_last;     /   
*(head)->tqh_last = (elm);               /   
(head)->tqh_last = &(elm)->field.tqe_next;        /   
  } while (0)
       应用:
   struct tailq_entry *subsystem;
   TAILQ_INSERT_TAIL(&g_tailqlist, subsystem, tailq);
   上述语句可以简单的看成是将subsystem插入到g_tailqlist列表的尾端。
   实际上执行的是:
         subsystem->tailq.tqe_next = NULL;            /   
subsystem->tailq.tqe_prev = g_tailqlist->tqh_last;(g_tailqlist->tqh_last是列表的最后一个元素(对于subsystem来说,即将成为它的上一个元素)的tqe_next地址。这个等式表示subsystem->tailq.tqe_prev指向的是上一个元素的tqe_next的地址)     /   
*g_tailqlist->tqh_last = subsystem; (这句话表示列表的最后一个元素是subsystem)              /   
g_tailqlist->tqh_last = &subsystem->tailq.tqe_next;(g_tailqlist->tqh_last指向列表的最后一个元素的tqe_next地址)
    
  
  #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {       /   
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    /   
  (elm)->field.tqe_next = (listelm);           /   
  *(listelm)->field.tqe_prev = (elm);          /   
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   /   
  } while (0)   
  作用:将elm插入到listelm的前面
  
  #define TAILQ_FIRST(head)       ((head)->tqh_first)   
  
  #define TAILQ_NEXT(elm, field)      ((elm)->field.tqe_next)   
 
  #define TAILQ_EMPTY(head)                       \  
    (TAILQ_FIRST(head) == TAILQ_END(head))

  #define TAILQ_FOREACH(var, head, field)                 \  
    for((var) = TAILQ_FIRST(head);                  \  
        (var) != TAILQ_END(head);                   \  
        (var) = TAILQ_NEXT(var, field))  

参考:http://blog.youkuaiyun.com/chen98765432101/article/details/56511598
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值