当前位置:首页>Linux>Linux内核IO多路复用epoll机制简介

Linux内核IO多路复用epoll机制简介

  • 2026-08-19 07:28:13
Linux内核IO多路复用epoll机制简介
  • 1. epoll 核心设计思想与数据结构
    • 核心结构体定义
  • 2. 三大核心系统调用源码深度剖析
    • 2.1 epoll_create / epoll_create1
    • 2.2 epoll_ctl (重点:事件控制与回调注册)
    • 2.3 epoll_wait
  • 3. 关键驱动机制:`ep_poll_callback` 的触发流程
  • 4. LT(水平触发)与 ET(边缘触发)内核实现差异
    • 机制对比总结

前言

本文旨在记录近期研读Java源码的学习心得与疑难问题。由于个人理解水平有限,文中内容难免存在疏漏,恳请读者不吝指正。

内核IO多路复用epoll机制简介

1. epoll 核心设计思想与数据结构

传统 select/poll 的根本缺陷在于:每次调用都需要将包含大量文件描述符(FD) combat 集合的数组从用户态拷贝到内核态,并且内核需要线性遍历整个集合来检查就绪状态,时间复杂度为 O(N)

epoll 采用了空间换时间以及事件驱动的设计思想。它在内核中维护了一个持久化的上下文,将“事件注册”与“事件等待”分离开来。

epoll 的底层数据结构主要依赖于红黑树(Red-Black Tree)双向链表(Doubly Linked List)

  • 红黑树:用于高效管理(增删改查)用户注册的所有 FD,保证了操作的时间复杂度为 O(logN)
  • 就绪链表:用于存放当前已经有事件触发的 FD。当进程调用 epoll_wait 时,内核只需直接检查该链表是否为空,时间复杂度为 O(1)

核心结构体定义

在 Linux 内核源码 fs/eventpoll.c 中,最关键的结构体是 struct eventpoll 和 struct epitem

// 代表一个 epoll 实例的内核对象
struct eventpoll {
/* 保护此结构体的自旋锁 */
spinlock_t lock;

/* 互斥锁,用于在修改 epoll 结构时进行同步 */
struct mutex mtx;

/* 等待队列,用于存放调用 epoll_wait 陷入阻塞的进程 */
wait_queue_head_t wq;

/* 用于 epoll 自身作为被监听对象(嵌套 epoll)时的等待队列 */
wait_queue_head_t poll_wait;

/* 就绪双向链表,存放所有就绪事件的 epitem */
struct list_head rdllist;

/* 红黑树根节点,用于管理所有被监听的 file */
struct rb_root_cached rbr;

/* 这是一个单链表,保存着执行完 epoll_wait 准备向用户空间复制,
       但由于某些原因(如 LT 模式)需要重新放回 rdllist 的节点 */

struct epitem *ovflist;

/* 属性:创建该实例的用户信息 */
struct user_struct *user;

/* 对应的 file 结构体指针 */
struct file *file;
// ... 省略部分统计与优化字段
};

每个被监听的文件描述符在内核中都会对应一个 struct epitem 结构体:

// 代表红黑树中的一个节点(即一个被监听的 FD)
struct epitem {
/* 红黑树节点,用于将当前结构挂载到 eventpoll 的 rbr 红黑树中 */
struct rb_node rbn;

/* 双向链表节点,用于将当前结构挂载到 eventpoll 的 rdllist 就绪链表中 */
struct list_head rdllink;

/* 处于下一级单链表 ovflist 的指针 */
struct epitem *next;

/* 包含被监听的 fd 和对应的 file 结构体指针 */
struct epoll_filefd ffd;

/* 轮询等待队列的个数 */
int nwait;

/* 包含当前项的等待队列项列表 */
struct list_head pwqlist;

/* 指向所属的 eventpoll 对象 */
struct eventpoll *ep;

/* 处于循环链表中的节点 */
struct list_head fllink;

/* 产生事件时的回调函数绑定的侦听器 */
struct wakeup_source __rcu *ws;

/* 用户注册的目标事件类型及私有数据 */
struct epoll_event event;
};


2. 三大核心系统调用源码深度剖析

epoll 体系由 epoll_createepoll_ctlepoll_wait 三个系统调用组成。以下结合内核源码分析其执行流程。

2.1 epoll_create / epoll_create1

epoll_create 核心任务是分配 struct eventpoll 内存,并创建一个匿名的 file 结构体,将其与一个未使用的文件描述符(fd)绑定,最后返回该 fd 给用户。这样设计可以使用户像操作普通文件一样操作 epoll(如 close)。

内核入口函数通常为 SYSCALL_DEFINE1(epoll_create1, int, flags),其内部调用 do_epoll_create

static int do_epoll_create(int flags) {
int error;
struct eventpoll *ep = NULL;
struct file *file;
int fd;

/* 检查非法 flags */
if (flags & ~EPOLL_CLOEXEC)
return -EINVAL;

/* 1. 分配 eventpoll 内存并初始化各数据结构 */
    error = ep_alloc(&ep);
if (error < 0)
return error;

/* 2. 获取一个未使用的文件描述符 fd */
    fd = get_unused_fd_flags(O_CLOEXEC | (flags & EPOLL_CLOEXEC));
if (fd < 0) {
        error = fd;
goto out_free_ep;
    }

/* 3. 创建匿名匿名文件,绑定 eventpoll_fops 操作集 */
/* 用户操作这个 fd 时的 read/write 等重定向到 epoll 的特有操作 */
    file = anon_inode_getfile("[eventpoll]", &eventpoll_fops, ep,
                 O_RDWR | (flags & EPOLL_CLOEXEC));
if (IS_ERR(file)) {
        error = PTR_ERR(file);
goto out_put_fd;
    }

    ep->file = file;
/* 4. 将 fd 与 file 建立映射,放入当前进程的 fd 数组中 */
    fd_install(fd, file);
return fd;

out_put_fd:
    put_unused_fd(fd);
out_free_ep:
    ep_free(ep);
return error;
}

2.2 epoll_ctl (重点:事件控制与回调注册)

epoll_ctl 负责对红黑树进行 ADDMODDEL 操作。其中 EPOLL_CTL_ADD 是最核心、最复杂的逻辑,它实现了底层驱动事件与 epoll 回调的对接。

SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
struct epoll_event __user *, event) {
struct error_check;
struct fd ftf;
struct eventpoll *ep;
struct epitem *epi;
struct epoll_event epds;

/* 从用户空间拷贝监听事件配置 */
if (ep_op_has_event(op) && copy_from_user(&epds, event, sizeof(epds)))
return -EFAULT;

    f = fdget(epfd); // 获取 epoll 本身的 file
    tf = fdget(fd);  // 获取目标被监听文件的 file

    ep = f.file->private_data;

    mutex_lock_nested(&ep->mtx, 0);

/* 在红黑树中查找该 fd 是否已经存在 */
    epi = ep_find(ep, tf.file, fd);

switch (op) {
case EPOLL_CTL_ADD:
if (!epi) {
            epds.events |= EPOLLERR | EPOLLHUP; // 默认监听错误事件
/* 核心函数:向红黑树插入节点,并挂载回调 */
            error = ep_insert(ep, &epds, tf.file, fd, full_check);
        } else {
            error = -EEXIST;
        }
break;
case EPOLL_CTL_DEL:
if (epi)
            error = ep_remove(ep, epi); // 从红黑树及就绪链表移除
else
            error = -ENOENT;
break;
case EPOLL_CTL_MOD:
if (epi) {
/* 修改已有节点的监听事件 */
            error = ep_modify(ep, epi, &epds);
        } else {
            error = -ENOENT;
        }
break;
    }
    mutex_unlock(&ep->mtx);
// ... 省略资源释放
return error;
}

深入分析 ep_insert 机制

ep_insert 内部通过调用目标文件的 poll 机制(针对网络套接字通常是 sock_poll,底层调用 tcp_poll),将自定义的回调函数注册到驱动的等待队列中。

static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
struct file *tfile, int fd, int full_check)
 {
int error;
struct epitem *epi;
struct ep_pqueue epq;

/* 1. 分配并初始化 epitem 节点 */
if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL)))
return -ENOMEM;

    INIT_LIST_HEAD(&epi->rdllink);
    INIT_LIST_HEAD(&epi->fllink);
    INIT_LIST_HEAD(&epi->pwqlist);
    epi->ep = ep;
    ep_set_ffd(&epi->ffd, tfile, fd);
    epi->event = *event;

/* 2. 初始化 ep_pqueue 适配器,设置回调包装函数 */
    epq.epi = epi;
    init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);

/* 3. 内部引发虚函数调用:tfile->f_op->poll() */
/* 该调用会触发 ep_ptable_queue_proc,从而将 ep_poll_callback 绑定到设备驱动 */
    revents = ep_item_poll(epi, &epq.pt, 1);

/* 4. 将 epitem 插入到 eventpoll 的红黑树中 */
    ep_rbtree_insert(ep, epi);

/* 5. 如果当前设备在注册时就已经有就绪事件,直接将其放入就绪链表,并唤醒可能在等待的进程 */
if ((revents & event->events) && !ep_is_linked(epi)) {
        list_add_tail(&epi->rdllink, &ep->rdllist);
if (waitqueue_active(&ep->wq))
            wake_up(&ep->wq);
    }
return 0;
}

在 ep_item_poll 的链路中,驱动程序通过调用 poll_wait 触发了先前设置的 ep_ptable_queue_proc

/* 驱动的 poll 机制回调该函数来建立等待项 */
static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
                 poll_table *pt)
 {
struct epitem *epi = ep_cb_from_pt(pt)->epi;
struct eppoll_entry *pwq;

if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) {
/* 初始化真正的驱动等待队列项,将其核心回调函数设置为 ep_poll_callback */
        init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
        pwq->whead = whead;
        pwq->base = epi;

/* 将等待项挂载到具体设备(如 Socket 接收缓冲区)的等待队列中 */
        add_wait_queue(whead, &pwq->wait);
        list_add_tail(&pwq->llink, &epi->pwqlist);
        epi->nwait++;
    } else {
        epi->nwait = -1;
    }
}

2.3 epoll_wait

epoll_wait 检查就绪链表 rdllist 是否有节点。如果没有,当前进程将让出 CPU,进入睡眠状态,直到被回调函数唤醒或超时。

SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,
int, maxevents, int, timeout) {
// ... 基础安全检查
return do_epoll_wait(epfd, events, maxevents, timeout);
}

static int do_epoll_wait(int epfd, struct epoll_event __user *events,
int maxevents, int timeout)
 {
struct fd f;
struct eventpoll *ep;

    f = fdget(epfd);
    ep = f.file->private_data;

/* 调用 ep_poll 获取就绪事件 */
    error = ep_poll(ep, events, maxevents, timeout);
return error;
}

ep_poll 实现逻辑

static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
int maxevents, long timeout)
 {
int res = 0, eavail;
unsigned long flags;
wait_queue_entry_t wait;

/* 1. 检查当前是否有可用就绪事件 */
if (list_empty(&ep->rdllist)) {
/* 没有事件,初始化一个等待队列项,关联当前进程 current */
        init_waitqueue_entry(&wait, current);
/* 挂载到 eventpoll 的等待队列 wq 中 */
        __add_wait_queue_exclusive(&ep->wq, &wait);

for (;;) {
/* 将进程状态设置为可中断睡眠(TASK_INTERRUPTIBLE) */
            set_current_state(TASK_INTERRUPTIBLE);

/* 再次检查是否有就绪事件或被信号中断 */
if (!list_empty(&ep->rdllist) || !timeout)
break;
if (signal_pending(current)) {
                res = -EINTR;
break;
            }

/* 让出 CPU,进入睡眠,等待 timeout 或被驱动回调唤醒 */
if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) {
                timeout = 0// 超时
break;
            }
        }
/* 被唤醒后,将进程状态恢复为运行,并移出等待队列 */
        __remove_wait_queue(&ep->wq, &wait);
        __set_current_state(TASK_RUNNING);
    }

/* 2. 检查是否有就绪事件需要拷贝给用户空间 */
    eavail = !list_empty(&ep->rdllist) || ep->ovflist != EP_NON_BLOCK;
if (eavail && res == 0) {
/* 核心函数:将事件数据从内核空间拷贝到用户空间的 events 数组 */
        res = ep_send_events(ep, events, maxevents);
    }
return res;
}


3. 关键驱动机制:ep_poll_callback 的触发流程

当网卡收到数据包时,硬件中断触发驱动程序。驱动程序将数据解析并放入对应的 socket 缓冲区。此时,驱动会调用原本挂载在 socket->sk_sleep 队列上的唤醒函数,这个唤醒函数就是我们在 epoll_ctl 中注册的 ep_poll_callback

以下是 ep_poll_callback 的核心源码:

static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, void *key) {
int campgrounds;
unsigned long flags;
/* 通过 wait 针脚反向查找到对应的 eppoll_entry,进而拿到 epitem */
struct epitem *epi = ep_item_from_wait(wait);
struct eventpoll *ep = epi->ep;
__poll_t pollflags = key_to_pollflags(key);

    spin_lock_irqsave(&ep->lock, flags);

/* 1. 检查驱动传来的事件掩码是否与用户注册的事件匹配 */
if (pollflags && !(pollflags & epi->event.events))
goto out_unlock;

/* 2. 判断当前 epitem 是否已经存在于就绪链表中,若存在则直接跳过防止重复添加 */
if (ep_is_linked(epi))
goto check_pages;

/* 3. 核心步骤:将就绪的 epitem 添加到 eventpoll 的就绪双向链表末尾 */
    list_add_tail(&epi->rdllink, &ep->rdllist);

check_pages:
/* 4. 唤醒在 epoll_wait 中阻塞等待的进程 */
if (waitqueue_active(&ep->wq)) {
        wake_up(&ep->wq);
    }

out_unlock:
    spin_unlock_irqrestore(&ep->lock, flags);
return 1;
}


4. LT(水平触发)与 ET(边缘触发)内核实现差异

LT(Level Triggered)和 ET(Edge Triggered)的本质区别在于:**当一次 epoll_wait 结束后,未处理完(或未完全读写完)的就绪 FD 是否会被自动重新放回 rdllist**

这一逻辑在 ep_send_events_proc(由 ep_send_events 调用)中实现:

static __initialize int ep_send_events_proc(void *priv, void *cookie, int call_nests) {
struct ep_send_events_data *esed = priv;
struct eventpoll *ep = esed->ep;
struct epitem *epi;
struct epoll_event __user *uevent = esed->events;
struct list_head txlist;

/* 1. 将 rdllist 上的所有节点转移到一个临时链表 txlist 中,清空 rdllist */
    list_splice_init(&ep->rdllist, &txlist);

/* 2. 遍历临时链表 txlist */
while (!list_empty(&txlist) && esed->res < esed->maxevents) {
        epi = list_first_entry(&txlist, struct epitem, rdllink);

/* 将其从临时链表移除 */
        list_del_init(&epi->rdllink);

/* 再次调用驱动的 poll 查看当前事件是否真实有效 */
        revents = ep_item_poll(epi, &pt, 1);
        revents &= epi->event.events;

if (revents) {
/* 将事件拷贝到用户空间 */
if (__put_user(revents, &uevent->events) ||
                __put_user(epi->event.data, &uevent->data)) {
/* 拷贝失败则将节点重新放回原就绪链表 */
                list_add(&epi->rdllink, &ep->rdllist);
return -EFAULT;
            }
            esed->res++;
            uevent++;

/* 3. 【核心区别所在】判断触发模式 */
if (epi->event.events & EPOLLET) {
/* ET 模式:既然已经通知了用户,就不再做任何操作 */
/* 这个节点不会被放回 rdllist,直到下一次设备状态改变触发回调 */
            } else {
/* LT 模式(默认):只要事件依然有效,就重新将节点放回 eventpoll 的 rdllist 中 */
                list_add_tail(&epi->rdllink, &ep->rdllist);
            }
        }
    }

/* 4. 如果还有未处理完的节点(例如 maxevents 小于实际就绪数),全部放回 rdllist */
if (!list_empty(&txlist)) {
        list_splice(&txlist, &ep->rdllist);
    }
return 0;
}

机制对比总结

特性 / 行为
水平触发 (LT)
边缘触发 (ET)
内核实现本质
事件复制到用户态后,若 FD 仍有事件,内核将其重新放回rdllist
事件复制到用户态后,内核直接将其从rdllist 移除,不再放回。
用户态下一次 epoll_wait
如果缓冲区还有数据未读完,epoll_wait 会立即返回,不会阻塞。
除非有新数据到达触发中断,否则即使缓冲区有剩余数据,epoll_wait 也会保持阻塞
推荐编程模式
支持阻塞与非阻塞 I/O,容错率高。
必须搭配非阻塞 I/O(Non-blocking I/O)
,且必须循环 read/write 直到返回 EAGAIN
内核上下文切换开销
相对较高,因为未读完的 FD 会反复触发 epoll_wait 返回。
极低,每个事件仅通知一次,对高并发大连接场景性能更优。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 16:29:47 HTTP/2.0 GET : https://f.mffb.com.cn/a/509629.html
  2. 运行时间 : 0.207720s [ 吞吐率:4.81req/s ] 内存消耗:4,458.27kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=8e19a2bfc3ee033a0b7e0cce712146d0
  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.001158s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001442s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000653s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000616s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001302s ]
  6. SELECT * FROM `set` [ RunTime:0.000611s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001451s ]
  8. SELECT * FROM `article` WHERE `id` = 509629 LIMIT 1 [ RunTime:0.001326s ]
  9. UPDATE `article` SET `lasttime` = 1787300987 WHERE `id` = 509629 [ RunTime:0.010354s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000604s ]
  11. SELECT * FROM `article` WHERE `id` < 509629 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001096s ]
  12. SELECT * FROM `article` WHERE `id` > 509629 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001113s ]
  13. SELECT * FROM `article` WHERE `id` < 509629 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001781s ]
  14. SELECT * FROM `article` WHERE `id` < 509629 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.015145s ]
  15. SELECT * FROM `article` WHERE `id` < 509629 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001641s ]
0.211413s