当前位置:首页>Linux>Linux内核链表:设计、实现

Linux内核链表:设计、实现

  • 2026-04-17 08:49:01
Linux内核链表:设计、实现

Linux内核链表:设计、实现

Linux内核中的链表实现堪称艺术:它通过嵌入和宏抽象,打造了一套类型无关、高效优雅的通用链表API。理解它,是读懂内核源代码的第一步,也是领略C语言宏编程之美的绝佳窗口。

1. 数据结构与核心原理

1.1 双向循环链表

Linux下链表是个双向循环链表

双向指每个表项包含两个指针:一个指向前一个表项(前向指针 prev),一个指向后一个表项(后向指针 next),支持双向遍历。

循环是指表头的前向指针指向表尾,表尾的后向指针指向表头。这样形成一个循环。

链表的数据结构如下:

struct list_head {    struct list_head *prev, *next;};

链表由表头表项构成,二者均使用 struct list_head 结构体。每个表项(或表头)里都有前向指针,后向指针,方便遍历。示意图如下:

术语统一:本文中“表项”指 struct list_head 结构体,“节点”指被嵌入的父结构体(如 struct person)。prev 称前向指针,next 称后向指针。

1.2 数据存储方式:嵌入而非指向

表项仅有 prev 和 next 两个指针,那么它如何存储实际数据呢?如果是我的话,可能就设计成这样:

struct list_head {    struct list_head *next;    struct list_head *prev;    void   *data;};

添加一个void *data 指针,指向数据。不过Linux下设计更巧妙。把表项嵌入到存储数据的数据结构里。假设有个person的结构体,里面有一些描述信息,然后所有的person都用链表链起来,如下:

struct person {    char name[64];    struct list_head list;    int  id;};

这里将 struct list_head 嵌入到 struct person 中。下文将 struct list_head 称为表项,将其所在的父结构体 struct person 称为节点(或表节点)。

形成的列表就如下:

这种“嵌入”方式避免了 void *data 带来的额外内存开销和类型不安全性,但代价是:当我们通过链表遍历拿到 struct list_head * 时,如何找回它所在的 struct person?这就引出了Linux内核中最重要的宏之一——container_of。

1.3 从表项到节点:container_of 原理

链表操作基于 struct list_head * 指针(即表项地址)。但实际业务操作的是 struct person 节点,因此需要一种方法从表项指针反推出所在节点的指针。  下面介绍container_of实现原理。

上图中表项的地址是ptr,节点的地址是p,这两个地址之间差一个offset。如果节点的地址是p,则表项的地址就为&p->list。则offset可以通过下面代码来计算。

struct person tmp;struct person *p = &tmp;offset = (long)&p->list - (long)p;

Linux 使用了一个小技巧:当 p 为空指针时,上面的计算就变为:

offset = (long)&((struct person*)NULL)->list - (long)NULL;//简化后offset = (long)&((struct person*)NULL)->list//知道了offset值,表项的地址减去offset就是节点的地址p = (long)ptr - (long)&((struct person*)NULL)->list

由此可见,offset 就是当结构体指针为 NULL 时,其成员变量的地址偏移量。有了offset,就可以根据表项地址(ptr)计算节点(p)的地址了。

Linux提供了offsetof宏来计算offset。提供了container_of宏从表项获取节点的地址。代码如下:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)/** * container_of - cast a member of a structure out to the containing structure * @ptr:        the pointer to the member. * @type:       the type of the container struct this is embedded in. * @member:     the name of the member within the struct. * */#define container_of(ptr, type, member) ({                      \        consttypeof( ((type *)0)->member ) *__mptr = (ptr);    \        //  ^^^^^^ 这一行的作用:声明一个与 member 同类型的临时指针        //  为什么要这样做?—— 做类型安全检查,防止传错 ptr 类型        (type *)( (char *)__mptr - offsetof(type,member) );})

因为获取节点的地址是个常用的操作,所以重新定义了一个宏list_entry宏。

/** * list_entry - get the struct for this entry * @ptr:        the &struct list_head pointer. * @type:       the type of the struct this is embedded in. * @member:     the name of the list_head within the struct. */#define list_entry(ptr, type, member) \        container_of(ptr, type, member)

【原理释疑】

为什么 ((TYPE *)0)->MEMBER 不会崩溃? 因为这里并没有真正解引用空指针。& 运算符只是计算成员相对于结构体起始地址的偏移量,编译器在编译期就能算出这个值,不会生成实际的内存访问指令。这是C语言标准允许的合法行为。

为什么需要强制类型转换 (TYPE *)0? 为了让编译器知道 MEMBER 是哪个结构体的成员,从而能正确计算其偏移地址。

2. 链表操作

在程序设计中,数据结构往往决定了算法。对于内核链表,一旦结构体确定,其核心操作逻辑也就随之清晰。

struct list_head {    struct list_head *next;    struct list_head *prev;};

知道了链表的结构体,就知道链表的操作怎么实现了。

2.1 表头定义以及初始化

Linux提供了LIST_HEAD这个宏来静态定义一个表头。

#define LIST_HEAD_INIT(name)    {&name, &name}#define LIST_HEAD(name)     \        struct list_head list = LIST_HEAD_INIT(name)

链表头初始化函数INIT_LIST_HEAD,初始化后的链表头prev、next都指向表头自己。

void INIT_LIST_HEAD(struct list_head *list{    list->prev = list;    list->next = list;}

2.2 判断链表是否为空

list_empty 函数判断链表是否为空

从INIT_LIST_HEAD函数可以知道。链表头的next、prev指针都指向自己,当next指针指向自己,则就表明链表为空。

staticinlineintlist_empty(conststruct list_head *head){    return READ_ONCE(head->next) == head;}

2.3 获取表节点地址

前面介绍了list_entry从表项指针获取节点指针。Linux还提供另外两个宏,用来获取链表第一个节点的地址和下一个节点的地址。

list_first_entry 返回链表第一个节点的地址,其中ptr指向表头。

#define list_first_entry(ptr, type, member) \        list_entry((ptr)->nexttype, member)

list_next_entry 返回当前节点的下一个节点的地址

/** * list_next_entry - get the next element in list * @pos:        the type * to cursor * @member:     the name of the list_head within the struct. */#define list_next_entry(pos, member) \        list_entry((pos)->member.next, typeof(*(pos)), member)

2.4 链表操作

list_addlist_add_tail 添加一个表项到表头和表尾

staticinlinevoidlist_add(struct list_head *newstruct list_head *head){        __list_add(new, head, head->next);}staticinlinevoidlist_add_tail(struct list_head *_new, struct list_head *head){        __list_add(_new, head->prev, head);}

这两个函数通过__list_add来实现。先找到prev 和 next节点。然后再进去插入。

static inline void __list_add(struct list_head *new,                              struct list_head *prev,                              struct list_head *next){        if (!__list_add_valid(new, prev, next))                return;        next->prev = new;        new->next = next;        new->prev = prev;        WRITE_ONCE(prev->next, new);}

list_del 删除节点时,先获取待删除节点的 prev 和 next,然后让 prev->next 指向 next,next->prev 指向 prev,从而将目标节点从链表中摘除。

static inline void __list_del(struct list_head *prev, struct list_head *next){        next->prev = prev;        prev->next = next;}staticinlinevoidlist_del(struct list_head *entry){        __list_del(entry->prev, entry->next);        entry->next = (struct list_head*)LIST_POISON1;        entry->prev = (struct list_head*)LIST_POISON2;}

删除后,内核还会对这两个指针“下毒”(poison):将 next 设为 LIST_POISON1(通常为 0x100),prev 设为 LIST_POISON2(通常为 0x200)。

代码来自 include/linux/poison.h

/********** include/linux/list.h **********//* * Architectures might want to move the poison pointer offset * into some well-recognized area such as 0xdead000000000000, * that is also not mappable by user-space exploits: */#ifdef CONFIG_ILLEGAL_POINTER_VALUEdefine POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)#elsedefine POISON_POINTER_DELTA 0#endif/* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */#define LIST_POISON1  ((void *) 0x100 + POISON_POINTER_DELTA)#define LIST_POISON2  ((void *) 0x200 + POISON_POINTER_DELTA)

毒药指针的效果

// 错误用法:删除后继续访问list_for_each_entry(pos, head, list) {    // 如果 pos 是已删除的节点,访问 pos->list.next 会触发 page fault}

内核将 0x100 和 0x200 映射到不可访问的保护区,一旦访问立即崩溃,帮助开发者快速定位 use-after-free 问题。 如果设置为 NULL,可能被误判为“空链表”而继续执行,掩盖 bug。

2.5 链表遍历

可以使用宏list_for_each来遍历链表。该宏跟着next指针就可以遍历所有表项。当next指向表头时,循环就结束。

#define list_for_each(pos, head) \        for (pos = (head)->nextpos != (head); pos = pos->next)

当在遍历中需要删除某个表项,需要用到safe版本的宏。 从前面的list_del函数可以看出,pos节点被删除,pos节点的next指针指向LIST_POISON1。所以宏list_for_each_safe使用了个n来保存下一个需要访问的节点。

#define list_for_each_safe(pos, n, head) \        for (pos = (head)->next, n = pos->nextpos != (head); \                pos = n, n = pos->next)

list_for_each遍历过程中,只是获取表项的地址,还需要调用list_entry获取节点的地址。所以提供了遍历节点的版本list_for_each_entry。

/** * list_for_each_entry  -       iterate over list of given type * @pos:        the type * to use as a loop cursor. * @head:       the head for your list. * @member:     the name of the list_head within the struct. */#define list_for_each_entry(pos, head, member)                          \        for (pos = list_first_entry(head, typeof(*pos), member);        \             &pos->member != (head);                    \             pos = list_next_entry(pos, member))

两者的核心区别在于:list_for_each 遍历的是 struct list_head *,需要手动调用 list_entry 转换;而 list_for_each_entry 直接遍历业务节点(如 struct person *),无需额外转换。

list_for_each的版本

list_for_each(pos, head) {        struct person *p = list_entry(pos, struct person, list);        fn(p);}

list_for_each_entry的版本

struct person *p;list_for_each_entry(p, head, list) {        fn(p);}

同样list_for_each_entry_safe是list_for_each_entry的safe版本,在遍历过程中需要删除的场景下使用。

list_for_each_entry_safe代码如下,使用n临时保存下一个要访问的节点:

/** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos:        the type * to use as a loop cursor. * @n:          another type * to use as temporary storage * @head:       the head for your list. * @member:     the name of the list_head within the struct. */#define list_for_each_entry_safe(pos, n, head, member)                  \        for (pos = list_first_entry(head, typeof(*pos), member),        \                n = list_next_entry(pos, member);                       \             &pos->member != (head);                                    \             pos = n, n = list_next_entry(n, member))

下面是一个典型的错误用法与正确用法的对比示例:

// ❌ 错误:遍历中删除会导致崩溃list_for_each_entry(p, head, list) {    if (p->id == target) {        list_del(&p->list);  // 删除后,p->list.next 变成毒药指针        free(p);             // 循环继续时会访问毒药指针 → 崩溃    }}// ✅ 正确:使用 safe 版本struct person *tmp;list_for_each_entry_safe(p, tmp, head, list) {    if (p->id == target) {        list_del(&p->list);        free(p);  // tmp 已保存下一个节点,安全    }}

当然,Linux 还提供了其他遍历方式(如反向遍历、从中间开始遍历等),本文不再展开。

3. 示例:约瑟夫环

理论讲完了,来看一个完整的例子。我们用 Linux 内核链表实现约瑟夫环问题。

约瑟夫环问题:n 个人围成一圈,从第 k 个人开始报数,数到 m 的人出列,下一个人继续从 1 报数,直到全部出列。问出列顺序。

3.1 代码实现

#include<stdio.h>#include<stdlib.h>#include"list.h"// 内核链表头文件struct person {    int id;                // 编号 1~n    struct list_head list; // 链表节点};// 获取下一个有效节点,如果到达哨兵则跳回第一个有效节点static struct person *next_person(struct person *cur, struct list_head *head){    struct list_head *next = cur->list.next;    if (next == head)        next = head->next;    return list_entry(next, struct person, list);}// 初始化 n 个人,编号 1~nstaticvoidinit_people(struct list_head *head, int n){    struct person *p;    for (int i = 1; i <= n; i++) {        p = malloc(sizeof(*p));        if (!p) {            perror("malloc failed");            exit(1);        }        p->id = i;        list_add_tail(&p->list, head);  // 尾插,保持编号顺序    }}// 约瑟夫环模拟staticvoidjosephus(struct list_head *head, int k, int m){    struct person *p, *tmp;    // 1. 找到第 k 个人作为起点    list_for_each_entry(p, head, list) {        if (p->id == k)            break;    }    printf("出列顺序: ");    while (!list_empty(head)) {        // 2. 报数,移动 m-1 次到达目标        for (int i = 1; i < m; i++) {            p = next_person(p, head);        }        // 3. 输出并删除当前节点        printf("%d ", p->id);        tmp = p;        p = next_person(p, head);  // 保存下一个起点        list_del(&tmp->list);        free(tmp);    }    printf("\n");}intmain(){    struct list_head people;    int n = 7, k = 3, m = 2;    INIT_LIST_HEAD(&people);    init_people(&people, n);    printf("约瑟夫环: n=%d, k=%d, m=%d\n", n, k, m);    josephus(&people, k, m);    return 0;}

4. 为什么要用宏?——从遍历说起

想想如何遍历一个链表?

1.取第一个节点2.判断是否结束:没结束就处理节点,结束了就完成3.取下一个节点,回到第 2 步

这个流程很简单,但用 C 语言直接写,你可能会陷入指针细节:

for (pos = head->nextpos != head; pos = pos->next) {    struct person *p = list_entry(pos, struct person, list);    fn(p);}

你在思考:next 指针、head 边界、list_entry 转换——这些和“处理每个 person”这个核心意图无关。

在 Python 中,你写 for p in person_list: process(p),语言帮你隐藏了迭代细节。C 语言没有这种语法,但 Linux 内核用宏创造了一个。

Linux 的解法:封装遍历逻辑 有了 list_first_entry 和 list_next_entry,遍历变成了:

对业务来说,遍历链表就变成了

list_for_each_entry(p, &person_list, list) {    fn(p);  // 只关心处理逻辑}

这带来了什么?

1.改变思维方式:从“怎么做”到“做什么”

不再思考 next 指针、边界判断、类型转换。只需要思考:给我第一个节点,给我下一个节点,直到结束。这是从指令式编程向声明式编程的转变。

 2.像函数式编程那样思考

函数式编程(如 Lisp、Haskell 等)有一个核心理念:用高阶函数抽象遍历模式。比如 Lisp 中处理列表

(mapcar #'fn list)   ;; 对每个元素应用 fn

Linux 链表遍历是这样:

list_for_each_entry(p, head, list) {    fn(p);}

思想是相通的——遍历逻辑被抽象了,你面对的是“序列”而非“链表”。

Lisp 教会我们:遍历是模式,处理是内容。

 3.宏创造新语法

C 语言没有 foreach,但宏可以创造它。list_for_each_entry 就像一个新的语言结构,专门表达“遍历链表”这个意图。

 4.代码即注释

看到 list_for_each_entry,你立即知道它在遍历链表。函数名本身就是文档。

通过宏抽象,链表遍历从“操作指针”变成了“处理序列”,这是一种思维层次的提升,也是函数式编程思想在 C 语言中的体现。

5. 总结

Linux 内核链表通过将链表项嵌入数据结构,实现了类型无关的通用链表操作。理解 container_of 和遍历宏是掌握内核链表的关键:

嵌入而非指向:传统链表用void *data指向数据,而Linux将链表节点嵌入到数据结构中。这样无需额外指针跳转,缓存更友好,且避免了类型转换的麻烦。宏封装逻辑:list_for_each_entry 等宏将遍历逻辑抽象,让你专注于业务安全遍历:_safe 版本支持遍历中删除节点

下一步建议:阅读内核源码 include/linux/list.h,尝试自己实现一个 list_for_each_entry_reverse 反向遍历宏。

附录:常用链表接口速查

分类
接口
作用
初始化LIST_HEAD(name)
静态定义并初始化表头
INIT_LIST_HEAD(ptr)
动态初始化表头
判断list_empty(head)
判断链表是否为空
添加/删除list_add(new, head)
添加到表头
list_add_tail(new, head)
添加到表尾
list_del(entry)
删除节点(节点变为毒药状态)
获取地址list_entry(ptr, type, member)
从表项指针获取节点指针
list_first_entry(head, type, member)
获取第一个节点
list_next_entry(pos, member)
获取下一个节点
遍历list_for_each(pos, head)
遍历表项指针(需配合 list_entry
list_for_each_entry(pos, head, member)
直接遍历节点(最常用
list_for_each_entry_safe(pos, n, head, member)
支持删除的遍历

提示:实际开发中,90% 的场景只用 list_for_each_entry、list_add_tail、list_del 和 list_entry。

说明:Linux 内核链表不记录链表长度,因为这会增加维护成本。如需长度信息,请自行用变量维护。


如果你觉得这篇文章有帮助,欢迎点赞、在看、转发支持~

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-17 14:08:04 HTTP/2.0 GET : https://f.mffb.com.cn/a/485252.html
  2. 运行时间 : 0.104295s [ 吞吐率:9.59req/s ] 内存消耗:5,096.79kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=a3f183a449b8777d6304473cbd30fdfb
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000427s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000877s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000307s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000281s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000568s ]
  6. SELECT * FROM `set` [ RunTime:0.006614s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000725s ]
  8. SELECT * FROM `article` WHERE `id` = 485252 LIMIT 1 [ RunTime:0.000612s ]
  9. UPDATE `article` SET `lasttime` = 1776406084 WHERE `id` = 485252 [ RunTime:0.000820s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000363s ]
  11. SELECT * FROM `article` WHERE `id` < 485252 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001327s ]
  12. SELECT * FROM `article` WHERE `id` > 485252 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002406s ]
  13. SELECT * FROM `article` WHERE `id` < 485252 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008749s ]
  14. SELECT * FROM `article` WHERE `id` < 485252 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002640s ]
  15. SELECT * FROM `article` WHERE `id` < 485252 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.005556s ]
0.105873s