宏名称 操作
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