当前位置:首页>Linux>深入浅出 Linux 内核(进程篇):进程切换之ARM体系架构

深入浅出 Linux 内核(进程篇):进程切换之ARM体系架构

  • 2026-06-30 22:18:43
深入浅出 Linux 内核(进程篇):进程切换之ARM体系架构

大家好~ 我是蟹老板

很多人问我,Linux 进程上下文切换,内核到底在忙啥?

说真的,这玩意确实是面试必问,线上出问题十有八九也和它沾边,但很多人背了无数遍流程,真到啃源码、查 bug 的时候,还是两眼一抹黑。

一、内核切换的指挥官 context_switch

进程切换说白了就两件事。第一件,把新进程的内存映射给换上,说白了就是换页表。第二件,把内核栈和 CPU 寄存器的状态,全给换成新进程的(换寄存器状态 + 内核栈指针)。就这两件事,看着简单,我估摸着有80%的人不懂。

在Linux内核里,这俩活儿全塞进了context_switch这个函数。用户空间那部分靠switch_mm,内核栈和寄存器靠switch_to。

我第一次看这段代码的时候,脑子里全是问号:为啥要分这么细?为啥判断 next->mm 是不是空?

后来才反应过来——内核线程和普通用户进程待遇不一样,内核线程没有用户地址空间啊!它的 mm_struct *mm 就是 NULL。

那内核线程跑的时候用谁的页表?用前一个进程的 active_mm(其实就是借用)。

/* * context_switch - 切换到新进程的内存地址空间和寄存器状态 */static __always_inline struct rq *context_switch(struct rq *rq, struct task_struct *prev,               struct task_struct *next, struct rq_flags *rf){  /* 进程切换前的准备工作,架构相关的前置处理、调度器状态更新全在这 */  prepare_task_switch(rq, prev, next);  /*   * 半虚拟化相关的钩子,ARM上基本是空实现,不用太纠结   * x86上主要是把页表重载和切换后端合并成一个hypercall   */  arch_start_context_switch(prev);  /*   * 这里是整个函数的核心分支,别死记硬背,就记4种场景:   * 内核线程 -> 内核线程 | 用户进程 -> 内核线程   * 内核线程 -> 用户进程 | 用户进程 -> 用户进程   */  if (!next->mm) {  // 要切到的是内核线程,它没有自己的用户地址空间    enter_lazy_tlb(prev->active_mm, next);  // 进入懒TLB模式,ARM里默认是空实现    next->active_mm = prev->active_mm;       // 内核线程直接蹭前一个进程的active_mm    if (prev->mm)                             // 前一个是用户进程,要给内存描述符的引用计数+1      mmgrab(prev->active_mm);    else                                       // 前一个也是内核线程,把它的active_mm清掉,防止野指针      prev->active_mm = NULL;  } else {                                     // 要切到的是用户进程,有独立的mm_struct    membarrier_switch_mm(rq, prev->active_mm, next->mm);  // 内存屏障,保证membarrier系统调用的时序正确    /*     * sys_membarrier要求在设置rq->curr和返回用户态之间,必须有一个smp_mb()     * 下面的switch_mm_irqs_off会提供这个屏障;如果前后进程mm相同,finish_task_switch里的mmdrop也会提供     */    // 核心!切换用户地址空间,ARM没实现专属的switch_mm_irqs_off,最终调用的就是switch_mm    switch_mm_irqs_off(prev->active_mm, next->mm, next);    if (!prev->mm) {                           // 前一个是内核线程,记录之前的active_mm,后面要释放引用      /* 这个mm的引用释放,会在finish_task_switch()里通过mmdrop()完成 */      rq->prev_mm = prev->active_mm;      prev->active_mm = NULL;    }  }  rq->clock_update_flags &= ~(RQCF_ACT_SKIP|RQCF_REQ_SKIP);  prepare_lock_switch(rq, next, rf);  /* 前面换完了内存地址空间,这里才是真正切换寄存器状态和内核栈! */  switch_to(prev, next, prev);  barrier();  // 编译器屏障,防止乱序,保证switch_to之后的代码一定在切换完成后执行  // 收尾工作,释放前一个进程的mm引用,处理调度器的剩余状态  return finish_task_switch(prev);}

是不是看着分支有点绕?没事,我当年也绕了好久。

内核线程永远跑在内核态,根本用不到用户地址空间,所以内核线程没有自己的mm,所以它借用上一个进程的active_mm。从用户进程切到内核线程时,要mmgrab增加引用计数;反过来从内核线程切到用户进程时,就把prev_mm记下来,后面finish_task_switch里再mmdrop。要是前一个也是内核线程,一定要把它的active_mm清掉,不然引用计数乱了,内存泄漏都是轻的,严重的直接 panic。

我以前写用户态代码的时候,从来没想过内核线程这么“寄生”。现在想想,调度器得时刻记得谁在用哪套页表,这活儿真不轻松。

二、内存管理机制:switch_mm

用户进程切换内存空间,主要靠switch_mm(或者switch_mm_irqs_off,x86有专门实现,ARM暂时没)。ARM上,这本质就是把新进程的页表基址写进TTBR0寄存器。

每个进程都有自己一套完整的虚拟地址空间,但物理内存是共享的。PGD(页全局目录)是最高层,下面是PTE,最终指向物理页。不同进程的PGD不一样,所以地址空间天然隔离。

ARMv7里,switch_mm长这样(我只把关键部分贴了出来):

staticinlinevoidswitch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk){#ifdef CONFIG_MMU    unsigned int cpu = smp_processor_id();    if (cache_ops_need_broadcast() && !cpumask_empty(mm_cpumask(next)) &&        !cpumask_test_cpu(cpu, mm_cpumask(next)))        __flush_icache_all();   /* 刷新CPU Core所有I-cache */    if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {        check_and_switch_context(next, tsk);        if (cache_is_vivt())            cpumask_clear_cpu(cpu, mm_cpumask(prev));    }#endif}

先处理I-cache。ARM是哈佛架构,I-cache和D-cache分开。当进程第一次被调度到某个核上,得把I-cache全刷掉,不然可能执行到旧指令。我以前在多核调试的时候,遇到过诡异的“代码没变但行为变了”的bug,现在回想,可能就是I-cache没刷干净。

2.1 别让 I-Cache 拖后腿

在 ARM 世界里,switch_mm 的核心任务就是改写 TTBR0(Translation Table Base Register 0)。这玩意儿就像是内存管理单元(MMU)的“导航仪”,指定了页全局目录(PGD)在哪儿。

但是,直接改 TTBR0 会出事吗?其实还有个更头疼的问题——缓存

为啥切换进程还要刷新 I-Cache(指令缓存)呢?

原因很简单:哈佛结构。在 ARM SMP 架构里,L1 缓存分成了独立的指令缓存(I-Cache)和数据缓存(D-Cache)。

如果一个进程从 CPU A 迁移到了 CPU B,CPU B 的 I-Cache 里可能还留着旧数据,这能行吗?

不用担心,switch_mm 里有个骚操作:

staticinlinevoidswitch_mm(struct mm_struct *prev, struct mm_struct *next,			     struct task_struct *tsk){#ifdef CONFIG_MMUunsigned int cpu = smp_processor_id();/*	 * 如果 next 进程刚迁移到这个 CPU,并且硬件需要广播 I-Cache 失效,	 * 就把整个 I-Cache 炸掉。	 */if (cache_ops_need_broadcast() &&	    !cpumask_empty(mm_cpumask(next)) &&	    !cpumask_test_cpu(cpu, mm_cpumask(next)))		_flush_icache_all();   // 这条指令会通过 CP15 的 c7 寄存器干掉 I-Cache/* 把当前 CPU 设置到 next 的 cpumask 里,表示这个进程现在也在这个核上跑过 */if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {check_and_switch_context(next, tsk);   // 核心:处理 ASID + 切 TTBR0if (cache_is_vivt())cpumask_clear_cpu(cpu, mm_cpumask(prev));	}#endif}

_flush_icache_all 在 ARMv7 SMP 上实际执行的是:

#define __flush_cache_all_v7_smp()	asm("mcr p15, 0, %0, c7, c1, 0" :: "r"(0))

MCR p15, 0, r0, c7, c1, 0 → CP15 协处理器的 c7, c1, 0 组合就是 ICIALLUIS(Inner Shareable 指令缓存全局失效)。

这就像给 CPU 下达了一个死命令:“把你的指令缓存全给我倒了,重新来!”

第一次看到这操作的时候我觉得:这也太暴力了吧?

但没办法,不暴力就会跑飞。

2.2 ASID 和 TLB:为啥 ARM 只给了 8 位?

TLB(快表),大家都知道它是为了加速地址转换的。但以前的 ARM 架构有个大毛病:进程一切换,TLB 就得全清。这就好比每次换台电视,都要把之前的记忆全抹掉,重新搜索信号,那速度能快吗?

为了解决这个问题,ARM 引入了 ASID(Address Space ID)。

ASID 只有 8 位,这意味着最多只能有 256 个独立的 ID。它是怎么玩的呢?

它把 TLB 分成了两类:

  • Global:属于内核的,谁来都不变(nG位为0)。

  • Process-specific:属于用户的,靠 ASID 来区分。

这样一来,进程 A 和进程 B 的 TLB 项因为 ASID 不同,根本不会打架。切换进程时,只要换个 ASID,旧的 TLB 项依然有效!这设计,真的绝了。

不过,8 位 ID 总有发完的时候。这时候就得触发 ASID 溢出机制,重新分配 ID 并刷新 TLB。这算是这个机制唯一的“阿喀琉斯之踵”吧。

来看这个切换的核心逻辑:

voidcheck_and_switch_context(struct mm_struct *mm, struct task_struct *tsk){    unsigned int cpu = smp_processor_id();    u64 asid;    /* * 因为更新页表基址和 ASID 没法做到原子操作,     * 所以咱们得先切到一个临时的保留状态,防止在这个间隙出岔子 [cite: 612, 622, 626]。     */    cpu_set_reserved_ttbr0();     asid = atomic64_read(&mm->context.id); /* 拿出现在进程的 ASID [cite: 613, 627] */    /* 如果号没溢出,万事大吉,走快车道直接切 [cite: 614, 628, 630] */    if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)         && atomic64_xchg(&per_cpu(active_asids, cpu), asid))        goto switch_mm_fastpath;    /* 号不够用了?那就得加锁重分配,还得刷一遍 TLB 和分支预测器 [cite: 615, 631, 642, 643] */    raw_spin_lock_irqsave(&cpu_asid_lock, flags);    asid = new_context(mm, cpu);    atomic64_set(&mm->context.id, asid);    local_flush_bp_all();     local_flush_tlb_all();     raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);switch_mm_fastpath:    cpu_switch_mm(mm->pgd, mm); /* 真正去改页表基址寄存器 TTBR0 [cite: 649] */}

local_flush_tlb_all 在 ARMv7 里实际是这条协处理器指令:

    staticinlinevoidlocal_flush_tlb_all(void)    {    	const int zero = 0;    	const unsigned int __tlb_flag = __cpu_tlb_flags;    	if (tlb_flag(TLB_WB))    		dsb(nshst);    	__local_flush_tlb_all();    	tlb_op(TLB_V7_UIS_FULL, "c8, c7, 0", zero);    	if (tlb_flag(TLB_BARRIER)) {    		dsb(nsh);    		isb();    	}    }

展开 tlb_op => mcr p15, 0, r0, c8, c7, 0CRn=c8, opc1=0, CRm=c7, opc2=0 → 查 ARM 手册就知道这是 TLBIALL统一 TLB 无效化也就是说一旦 ASID 用光,所有进程的 TLB 条目一起陪葬——性能会抖一下,但至少不会错。

三、 switch_to

前面都在说用户空间地址切换,但真正让 CPU 执行流的“灵魂”转移的,是 switch_to

先复习下switch_to的宏定义,很多人搞不懂为啥要传三个参数,prevnextprev

#define switch_to(prev,next,last) \do\  __complete_pending_tlbi(); \  last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \} while (0)

这里的核心是__switch_to,纯汇编实现,也是整个进程切换的最终落脚点。

它把前一个进程(prev)的 CPU 寄存器状态保存起来,然后把下一个进程(next)之前保存的寄存器状态恢复出来,包括栈指针 sp 和程序计数器 pc。等 pc 寄存器被换成 next 进程的值,CPU 接下来就会执行 next 进程的指令,进程切换就彻底完成了。

ENTRY(__switch_to)UNWIND(.fnstart )UNWIND(.cantunwind )  @ 入参:  @ R0:prev进程的task_struct  @ R1:prev进程的thread_info  @ R2:next进程的thread_info  add ip, r1, #TI_CPU_SAVE   @ ip寄存器 = prev进程thread_info里cpu_context的地址  @ 把prev进程的r4-sl、fp、sp、lr寄存器,保存到prev的cpu_context里  ARM( stmia ip!, {r4 - sl, fp, sp, lr} )  THUMB( stmia ip!, {r4 - sl, fp} )  THUMB( str sp, [ip], #4 )  THUMB( str lr, [ip], #4 )  @ 把next进程的TLS线程本地存储指针读到r4、r5里  ldr r4, [r2, #TI_TP_VALUE]  ldr r5, [r2, #TI_TP_VALUE + 4]#ifdef CONFIG_CPU_USE_DOMAINS  mrc p15, 0, r6, c3, c0, 0  @ 读域访问控制寄存器DACR  str r6, [r1, #TI_CPU_DOMAIN]@ 把旧的DACR保存到prev的thread_info里  ldr r6, [r2, #TI_CPU_DOMAIN]@ 从next的thread_info里读新的DACR#endif  switch_tls r1, r4, r5, r3, r7 @ 切换TLS线程本地存储#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)  ldr r7, [r2, #TI_TASK]  ldr r8, =__stack_chk_guard  .if (TSK_STACK_CANARY > IMM12_MASK)  add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK  .endif  ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]#endif#ifdef CONFIG_CPU_USE_DOMAINS  mcr p15, 0, r6, c3, c0, 0  @ 把新的DACR写到寄存器里,完成域访问权限切换#endif  mov r5, r0                   @ 把prev进程的task_struct指针暂存到r5  add r4, r2, #TI_CPU_SAVE     @ r4 = next进程thread_info里cpu_context的地址  @ 调用线程切换的通知链,内核里其他模块可以通过这个钩子感知进程切换  ldr r0, =thread_notify_head  mov r1, #THREAD_NOTIFY_SWITCH  bl atomic_notifier_call_chain#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)  str r7, [r8] @ 更新栈溢出保护的canary值#endif  THUMB( mov ip, r4 )  mov r0, r5 @ 把prev进程的task_struct指针放到r0,作为函数返回值  @ 核心!从next的cpu_context里,把之前保存的寄存器全恢复出来  @ 包括r4-sl、fp、sp、pc,sp恢复了,内核栈就切到next进程了  @ pc被赋值成next进程之前保存的lr,CPU就会跳转到next进程的执行流  ARM( ldmia r4, {r4 - sl, fp, sp, pc} )  THUMB( ldmia ip!, {r4 - sl, fp} )  THUMB( ldr sp, [ip], #4 )  THUMB( ldr pc, [ip] )UNWIND(.fnend )ENDPROC(__switch_to)

看到没,整个进程切换的最后一步,就靠stmialdmia这两条批量内存指令。stmia把当前进程的寄存器全存到内存里。

最骚的就是最后一条 ldmia r4, {..., pc}

sp 被换成了 next 的内核栈,pc 被换成了 next 上一次被切换出去时保存的返回地址。

于是 CPU 就神奇地开始在 next 的上下文里跑起来了

我第一次看这段汇编时,盯着 pc 的变化愣了三分钟——

这不就是传说中的“魂穿”吗?

写到这里,又是几千字了。

说实话,ARM 的进程切换比 x86 清爽不少(至少没那么多段寄存器要折腾),但 ASID 只有 8 位这件事,每次想到都让我觉得有点像“当年设计寄存器的大佬喝了假酒”。

不过话说回来,256 个 ASID 在嵌入式场景也够用——毕竟谁没事在一颗 Cortex-A 上跑几百个进程啊?

你要真跑那么多了,那刷 TLB 的代价你就自己受着吧,反正 Linux 内核已经给了你选择:要么忍受 TLB miss 多一点,要么偶尔来一次全局冲刷。

最后送大家一句我踩坑总结的真理:

调试进程切换 crash,第一眼看 mm->active_mm 是不是 NULL,第二眼看 TTBR0 寄没寄。

别问我怎么知道的,问就是又写Bug了。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 09:46:03 HTTP/2.0 GET : https://f.mffb.com.cn/a/489770.html
  2. 运行时间 : 0.113117s [ 吞吐率:8.84req/s ] 内存消耗:4,427.14kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=b520c32025ffbe65f81c48e45e0f2f0d
  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.000503s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000826s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000310s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000290s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000530s ]
  6. SELECT * FROM `set` [ RunTime:0.000235s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000713s ]
  8. SELECT * FROM `article` WHERE `id` = 489770 LIMIT 1 [ RunTime:0.000898s ]
  9. UPDATE `article` SET `lasttime` = 1783043163 WHERE `id` = 489770 [ RunTime:0.013238s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.005406s ]
  11. SELECT * FROM `article` WHERE `id` < 489770 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000667s ]
  12. SELECT * FROM `article` WHERE `id` > 489770 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000460s ]
  13. SELECT * FROM `article` WHERE `id` < 489770 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001114s ]
  14. SELECT * FROM `article` WHERE `id` < 489770 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.004856s ]
  15. SELECT * FROM `article` WHERE `id` < 489770 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.013173s ]
0.114684s