QUEUE - Linux手册页

时间:2019-08-20 17:59:48  来源:igfitidea点击:

Section: C Library Functions (3)

BSD mandoc

名称

SLIST_EMPTY SLIST_ENTRY SLIST_FIRST SLIST_FOREACH SLIST_HEAD SLIST_HEAD_INITIALIZER SLIST_INIT SLIST_INSERT_AFTER SLIST_INSERT_HEAD SLIST_NEXT SLIST_REMOVE_HEAD SLIST_REMOVE STAILQ_CONCAT STAILQ_EMPTY STAILQ_ENTRY STAILQ_FIRST STAILQ_FOREACH STAILQ_HEAD STAILQ_HEAD_INITIALIZER STAILQ_INIT STAILQ_INSERT_AFTER STAILQ_INSERT_HEAD STAILQ_INSERT_TAIL STAILQ_NEXT STAILQ_REMOVE_HEAD STAILQ_REMOVE LIST_EMPTY LIST_ENTRY LIST_FIRST LIST_FOREACH LIST_HEAD LIST_HEAD_INITIALIZER LIST_INIT LIST_INSERT_AFTER LIST_INSERT_BEFORE LIST_INSERT_HEAD LIST_NEXT LIST_REMOVE TAILQ_CONCAT TAILQ_EMPTY TAILQ_ENTRY TAILQ_FIRST TAILQ_FOREACH TAILQ_FOREACH_REVERSE TAILQ_HEAD TAILQ_HEAD_INITIALIZER TAILQ_INIT TAILQ_INSERT_AFTER TAILQ_INSERT_BEFORE TAILQ_INSERT_HEAD TAILQ_INSERT_TAIL TAILQ_LAST TAILQ_NEXT TAILQ_PREV TAILQ_REMOVE-单链接列表,单链接尾部队列,列表和尾部队列的实现

语法

在sys / queue中.h Fn SLIST_EMPTY SLIST_HEAD *头Fn SLIST_ENTRY类型Fn SLIST_FIRST SLIST_HEAD 头Fn SLIST_FOREACH类型var SLIST_HEAD *头SLIST_ENTRY NAME Fn SLIST_HEAD HEADNAME类型Fn SLIST_HEAD_INITIALIZER SLIST_HEAD * SLIST_ENTRY NAME FN SLIST_INSERT_HEAD SLIST_HEAD 头型榆树SLIST_ENTRY NAME FN SLIST_NEXT TYPE *榆树SLIST_ENTRY NAME FN SLIST_REMOVE_HEAD SLIST_HEAD *头SLIST_ENTRY NAME FN SLIST_REMOVE SLIST_HEAD 头型榆树TYPE SLIST_ENTRY NAME FN STAILQ_CONCAT STAILQ_HEAD *头像1 STAILQ_HEAD * HEAD2 FN STAILQ_EMPTY STAILQ_HEAD *头FN STAILQ_ENTRY FN型STAILQ_FIRST STAILQ_HEAD *头FN STAILQ_FOREACH TYPE *变种STAILQ_HEAD *头STAILQ_ENTRY NAME FN STAILQ_HEAD HEADNAME FN型STAILQ_HEAD_INITIALIZER STAILQ_HEAD头FN STAILQ_INIT STAILQ_HEAD *头FN STAILQ_INSERT_AFTER STAILQ_HEAD 头型listelm TYPE *榆树STAILQ_ENTRY NAME FN STAILQ_INSERT_HEAD STAILQ_HEAD 头型elm STA ILQ_ENTRY NAME FN STAILQ_INSERT_TAIL STAILQ_HEAD 头型榆树STAILQ_ENTRY NAME FN STAILQ_NEXT TYPE *榆树STAILQ_ENTRY NAME FN STAILQ_REMOVE_HEAD STAILQ_HEAD *头STAILQ_ENTRY NAME FN STAILQ_REMOVE STAILQ_HEAD 头型榆树TYPE STAILQ_ENTRY NAME FN LIST_EMPTY LIST_HEAD *头FN LIST_ENTRY FN型LIST_FIRST LIST_HEAD *头Fn LIST_FOREACH TYPE * var LIST_HEAD *头LIST_ENTRY NAME Fn LIST_HEAD HEADNAME TYPE Fn LIST_HEAD_INITIALIZER LIST_HEAD头Fn LIST_INIT LIST_HEAD *头Fn LIST_INSERT_AFTER TYPE * LISTELM TYPE * elm LIST_ENTRY NAMEF榆树LIST_ENTRY NAME FN LIST_NEXT TYPE *榆树LIST_ENTRY NAME FN LIST_REMOVE TYPE *榆树LIST_ENTRY NAME FN TAILQ_CONCAT TAILQ_HEAD *头像1 TAILQ_HEAD * HEAD2 TAILQ_ENTRY NAME FN TAILQ_EMPTY TAILQ_HEAD *头FN TAILQ_ENTRY FN型TAILQ_FIRST TAILQ_HEAD *头FN TAILQ_FOREACH TYPE *变种TAILQ_HEAD *头TAILQ_ENTRY NAME Fn TAILQ_FOREACH_REVERSE TYPE * var T AILQ_HEAD *头HEADNAME TAILQ_ENTRY NAME FN TAILQ_HEAD HEADNAME FN型TAILQ_HEAD_INITIALIZER TAILQ_HEAD头FN TAILQ_INIT TAILQ_HEAD *头FN TAILQ_INSERT_AFTER TAILQ_HEAD 头型listelm TYPE *榆树TAILQ_ENTRY NAME FN TAILQ_INSERT_BEFORE TYPE * listelm TYPE *榆树TAILQ_ENTRY NAME FN TAILQ_INSERT_HEAD TAILQ_HEAD 头型榆树TAILQ_ENTRY NAME Fn TAILQ_INSERT_TAIL TAILQ_HEAD 头类型elm TAILQ_ENTRY名称Fn TAILQ_LAST TAILQ_HEAD *头HEADNAME Fn TAILQ_NEXT TYPE * elm TAILQ_ENTRY名称Fn TAILQ_PREV TYPE * elm头名TAILQ_VEQ

说明

这些宏定义了四种类型的数据结构并对其进行操作:单链接列表,单链接尾队列,列表和尾队列。所有四个结构都支持以下功能:

Insertion of a new entry at the head of the list.

Insertion of a new entry after any element in the list.

O(1) removal of an entry from the head of the list.

Forward traversal through the list.

单链接列表是四种数据结构中最简单的列表,并且仅支持上述功能。单链接列表非常适合具有大型数据集且很少或没有删除的应用程序,或者是实现LIFO队列的理想选择。单链接列表添加以下功能:

O(n) removal of any entry in the list.

单链接尾部队列添加以下功能:

Entries can be added at the end of a list.

O(n) removal of any entry in the list.

They may be concatenated.

然而:

All list insertions must specify the head of the list.

Each head entry requires two pointers rather than one.

Code size is about 15% greater and operations run about 20% slower
than singly-linked lists.

单链接尾部队列非常适合具有大型数据集且删除很少或没有删除的应用程序,或者是实现FIFO队列的理想选择。

所有双向链接的数据结构类型(列表和尾队列)还允许:

Insertion of a new entry before any element in the list.

O(1) removal of any entry in the list.

然而:

Each element requires two pointers rather than one.

Code size and execution time of operations (except for removal) is about
twice that of the singly-linked data-structures.

链表是双链数据结构中最简单的一种。他们在上面添加了以下功能:

They may be traversed backwards.

然而:

To traverse backwards, an entry to begin the traversal and the list in
which it is contained must be specified.

尾部队列添加以下功能:

Entries can be added at the end of a list.

They may be traversed backwards, from tail to head.

They may be concatenated.

然而:

All list insertions and removals must specify the head of the list.

Each head entry requires two pointers rather than one.

Code size is about 15% greater and operations run about 20% slower
than singly-linked lists.

在宏定义中,Fa TYPE是用户定义的结构的名称,该结构必须包含名为Fa NAME的SLIST_ENTRY STAILQ_ENTRY LIST_ENTRY或TAILQ_ENTRY类型的字段。 Fa HEADNAME参数是必须使用宏SLIST_HEAD STAILQ_HEAD LIST_HEAD或TAILQ_HEAD声明的用户定义结构的名称。有关如何使用这些宏的进一步说明,请参见下面的示例。

Singly-linked lists

单链接列表以SLIST_HEAD宏定义的结构为首。该结构包含一个指向列表中第一个元素的指针。为了最小的空间和指针操作开销,元素被单链接在一起,但以任意元素的O(n)删除为代价。可以将新元素添加到列表中现有元素之后或列表的顶部。 Fa SLIST_HEAD结构的声明如下:

SLIST_HEAD(HEADNAME, TYPE) head;

其中Fa HEADNAME是要定义的结构的名称,而Fa TYPE是要链接到列表中的元素的类型。指向列表开头的指针以后可以声明为:

struct HEADNAME *headp;

(用户可以选择名字head和headp。)

宏SLIST_HEAD_INITIALIZER评估为列表Fa head的初始化程序。

如果列表中没有元素,则宏SLIST_EMPTY的计算结果为true。

宏SLIST_ENTRY声明一个连接列表中元素的结构。

宏SLIST_FIRST返回列表中的第一个元素;如果列表为空,则返回NULL。

宏SLIST_FOREACH向前遍历Fa head引用的列表,依次将每个元素分配给Fa var。

宏SLIST_INIT初始化Fa head引用的列表。

宏SLIST_INSERT_HEAD将新元素Fa elm插入列表的开头。

宏SLIST_INSERT_AFTER在元素Fa listelm之后插入新元素Fa elm。

宏SLIST_NEXT返回列表中的下一个元素。

宏SLIST_REMOVE_HEAD从列表的开头删除元素Fa elm。为了获得最佳效率,从列表开头删除的元素应显式使用此宏,而不是通用Fa SLIST_REMOVE宏。

宏SLIST_REMOVE从列表中删除元素Fa elm。

Singly-linked list example

SLIST_HEAD(slisthead, entry) head =
    SLIST_HEAD_INITIALIZER(head);
struct slisthead *headp;                /* Singly-linked List
                                           head. */
struct entry {
        ...
        SLIST_ENTRY(entry) entries;     /* Singly-linked List. */
        ...
} *n1, *n2, *n3, *np;

SLIST_INIT(&head);                      /* Initialize the list. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
SLIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
SLIST_INSERT_AFTER(n1, n2, entries);

SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
free(n2);

n3 = SLIST_FIRST(&head);
SLIST_REMOVE_HEAD(&head, entries);      /* Deletion from the head. */
free(n3);
                                        /* Forward traversal. */
SLIST_FOREACH(np, &head, entries)
        np-> ...

while (!SLIST_EMPTY(&head)) {           /* List Deletion. */
        n1 = SLIST_FIRST(&head);
        SLIST_REMOVE_HEAD(&head, entries);
        free(n1);
}

Singly-linked tail queues

单链接尾队列由STAILQ_HEAD宏定义的结构开头。该结构包含一对指针,一个指针指向尾部队列中的第一个元素,另一个指针指向尾部队列中的最后一个元素。为了最小的空间和指针操作开销,元素被单链接在一起,但以任意元素的O(n)删除为代价。可以将新元素添加到尾部队列中现有元素之后,尾部队列的开头或尾部队列的末尾。 Fa STAILQ_HEAD结构声明如下:

STAILQ_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,而TYPE是要链接到尾部队列中的元素的类型。稍后可以将指向尾部队列头部的指针声明为:

struct HEADNAME *headp;

(用户可以选择名字head和headp。)

宏STAILQ_HEAD_INITIALIZER评估为尾部队列Fa head的初始化程序。

宏STAILQ_CONCAT将以fa head2为头的尾部队列连接到以fa head1为头的尾部队列中,从前者中删除所有条目。

如果尾部队列中没有任何项目,则宏STAILQ_EMPTY的计算结果为true。

宏STAILQ_ENTRY声明一个连接尾部队列中元素的结构。

宏STAILQ_FIRST返回尾部队列中的第一项;如果尾部队列为空,则返回NULL。

宏STAILQ_FOREACH沿正向遍历Fa头引用的尾部队列,并将每个元素依次分配给Fa var。

宏STAILQ_INIT初始化Fa head引用的尾部队列。

宏STAILQ_INSERT_HEAD将新元素Fa elm插入尾部队列的头部。

宏STAILQ_INSERT_TAIL将新元素Fa elm插入尾部队列的末尾。

宏STAILQ_INSERT_AFTER在元素Fa listelm之后插入新元素Fa elm。

宏STAILQ_NEXT返回尾部队列中的下一个项目,如果为NULL,则该项目为最后一个。

宏STAILQ_REMOVE_HEAD删除尾部队列开头的元素。为了获得最佳效率,从尾部队列的开头移除的元素应显式使用此宏,而不是一般的Fa STAILQ_REMOVE宏。

宏STAILQ_REMOVE从尾部队列中删除元素Fa elm。

Singly-linked tail queue example

STAILQ_HEAD(stailhead, entry) head =
    STAILQ_HEAD_INITIALIZER(head);
struct stailhead *headp;                /* Singly-linked tail queue head. */
struct entry {
        ...
        STAILQ_ENTRY(entry) entries;    /* Tail queue. */
        ...
} *n1, *n2, *n3, *np;

STAILQ_INIT(&head);                     /* Initialize the queue. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
STAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
STAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
STAILQ_INSERT_AFTER(&head, n1, n2, entries);
                                        /* Deletion. */
STAILQ_REMOVE(&head, n2, entry, entries);
free(n2);
                                        /* Deletion from the head. */
n3 = STAILQ_FIRST(&head);
STAILQ_REMOVE_HEAD(&head, entries);
free(n3);
                                        /* Forward traversal. */
STAILQ_FOREACH(np, &head, entries)
        np-> ...
                                        /* TailQ Deletion. */
while (!STAILQ_EMPTY(&head)) {
        n1 = STAILQ_FIRST(&head);
        STAILQ_REMOVE_HEAD(&head, entries);
        free(n1);
}
                                        /* Faster TailQ Deletion. */
n1 = STAILQ_FIRST(&head);
while (n1 != NULL) {
        n2 = STAILQ_NEXT(n1, entries);
        free(n1);
        n1 = n2;
}
STAILQ_INIT(&head);

Lists

列表以LIST_HEAD宏定义的结构为首。该结构包含一个指向列表中第一个元素的指针。元素被双重链接,以便可以在不遍历列表的情况下删除任意元素。可以在现有元素之后,现有元素之前或列表顶部将新元素添加到列表中。 Fa LIST_HEAD结构的声明如下:

LIST_HEAD(HEADNAME, TYPE) head;

其中Fa HEADNAME是要定义的结构的名称,而Fa TYPE是要链接到列表中的元素的类型。指向列表开头的指针以后可以声明为:

struct HEADNAME *headp;

(用户可以选择名字head和headp。)

宏LIST_HEAD_INITIALIZER评估为列表Fa head的初始化程序。

如果列表中没有元素,则宏LIST_EMPTY的计算结果为true。

宏LIST_ENTRY声明一个连接列表中元素的结构。

宏LIST_FIRST返回列表中的第一个元素;如果列表为空,则返回NULL。

宏LIST_FOREACH沿正向遍历Fa头引用的列表,并将每个元素依次分配给Fa var。

宏LIST_INIT初始化Fa head引用的列表。

宏LIST_INSERT_HEAD将新元素Fa elm插入列表的开头。

宏LIST_INSERT_AFTER在元素Fa listelm之后插入新元素Fa elm。

宏LIST_INSERT_BEFORE在元素Fa listelm之前插入新元素Fa elm。

宏LIST_NEXT返回列表中的下一个元素;如果为最后一个,则返回NULL。

宏LIST_REMOVE从列表中删除元素Fa elm。

List example

LIST_HEAD(listhead, entry) head =
    LIST_HEAD_INITIALIZER(head);
struct listhead *headp;                 /* List head. */
struct entry {
        ...
        LIST_ENTRY(entry) entries;      /* List. */
        ...
} *n1, *n2, *n3, *np, *np_temp;

LIST_INIT(&head);                       /* Initialize the list. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
LIST_INSERT_HEAD(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
LIST_INSERT_AFTER(n1, n2, entries);

n3 = malloc(sizeof(struct entry));      /* Insert before. */
LIST_INSERT_BEFORE(n2, n3, entries);

LIST_REMOVE(n2, entries);               /* Deletion. */
free(n2);
                                        /* Forward traversal. */
LIST_FOREACH(np, &head, entries)
        np-> ...

while (!LIST_EMPTY(&head)) {            /* List Deletion. */
        n1 = LIST_FIRST(&head);
        LIST_REMOVE(n1, entries);
        free(n1);
}

n1 = LIST_FIRST(&head);                 /* Faster List Deletion. */
while (n1 != NULL) {
        n2 = LIST_NEXT(n1, entries);
        free(n1);
        n1 = n2;
}
LIST_INIT(&head);

Tail queues

尾部队列以TAILQ_HEAD宏定义的结构为首。该结构包含一对指针,一个指针指向尾部队列中的第一个元素,另一个指针指向尾部队列中的最后一个元素。元素被双重链接,以便可以在不遍历尾部队列的情况下删除任意元素。可以在现有元素之后,现有元素之前,尾部队列的开头或尾部队列的末尾将新元素添加到尾部队列中。 Fa TAILQ_HEAD结构的声明如下:

TAILQ_HEAD(HEADNAME, TYPE) head;

其中HEADNAME是要定义的结构的名称,而TYPE是要链接到尾部队列中的元素的类型。稍后可以将指向尾部队列头部的指针声明为:

struct HEADNAME *headp;

(用户可以选择名字head和headp。)

宏TAILQ_HEAD_INITIALIZER求出尾部队列Fa head的初始化器。

宏TAILQ_CONCAT将以Fa head2为头的尾部队列连接到以Fa head1为头的尾部队列中,从前者中删除所有条目。

如果尾部队列中没有任何项目,则宏TAILQ_EMPTY的计算结果为true。

宏TAILQ_ENTRY声明一个连接尾部队列中元素的结构。

宏TAILQ_FIRST返回尾部队列中的第一项;如果尾部队列为空,则返回NULL。

宏TAILQ_FOREACH沿正向遍历Fa头引用的尾部队列,并将每个元素依次分配给Fa var。如果循环正常完成或没有元素,则将Fa var设置为NULL。

宏TAILQ_FOREACH_REVERSE反向遍历Fa头引用的尾部队列,并将每个元素依次分配给Fa var。

宏TAILQ_INIT初始化Fa head引用的尾队列。

宏TAILQ_INSERT_HEAD将新元素Fa elm插入尾部队列的头部。

宏TAILQ_INSERT_TAIL将新元素Fa elm插入尾部队列的末尾。

宏TAILQ_INSERT_AFTER在元素Fa listelm之后插入新元素Fa elm。

宏TAILQ_INSERT_BEFORE在元素Fa listelm之前插入新元素Fa elm。

宏TAILQ_LAST返回尾部队列中的最后一项。如果尾部队列为空,则返回值为NULL

宏TAILQ_NEXT返回尾部队列中的下一项;如果该项是最后一项,则返回NULL。

宏TAILQ_PREV返回尾部队列中的上一项,如果该项是第一项,则返回NULL。

宏TAILQ_REMOVE从尾部队列中删除元素Fa elm。

Tail queue example

TAILQ_HEAD(tailhead, entry) head =
    TAILQ_HEAD_INITIALIZER(head);
struct tailhead *headp;                 /* Tail queue head. */
struct entry {
        ...
        TAILQ_ENTRY(entry) entries;     /* Tail queue. */
        ...
} *n1, *n2, *n3, *np;

TAILQ_INIT(&head);                      /* Initialize the queue. */

n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
TAILQ_INSERT_HEAD(&head, n1, entries);

n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
TAILQ_INSERT_TAIL(&head, n1, entries);

n2 = malloc(sizeof(struct entry));      /* Insert after. */
TAILQ_INSERT_AFTER(&head, n1, n2, entries);

n3 = malloc(sizeof(struct entry));      /* Insert before. */
TAILQ_INSERT_BEFORE(n2, n3, entries);

TAILQ_REMOVE(&head, n2, entries);       /* Deletion. */
free(n2);
                                        /* Forward traversal. */
TAILQ_FOREACH(np, &head, entries)
        np-> ...
                                        /* Reverse traversal. */
TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
        np-> ...
                                        /* TailQ Deletion. */
while (!TAILQ_EMPTY(&head)) {
        n1 = TAILQ_FIRST(&head);
        TAILQ_REMOVE(&head, n1, entries);
        free(n1);
}
                                        /* Faster TailQ Deletion. */
n1 = TAILQ_FIRST(&head);
while (n1 != NULL) {
        n2 = TAILQ_NEXT(n1, entries);
        free(n1);
        n1 = n2;
}

TAILQ_INIT(&head);

遵循规范

不在POSIX.1,POSIX.1-2001或POSIX.1-2008中。存在于BSD上。队列功能最早出现在BSD 4.4中

另外参见

insque(3)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/