聊一聊 C# 线程切换后上下文都去了哪里

💡 原文中文,约10400字,阅读约需25分钟。
📝

内容提要

本文从.NET高级调试的角度分析了Windows中线程上下文切换的问题,通过观察线程栈和寄存器上下文,发现用户线程拥有两个线程栈,分别为用户态栈和内核态栈。调用线程执行Sleep(1)后,还会保存现场,保存在内核态线程栈的InitialStack ~ KernelStack之间。这个分析加深了对操作系统的理解。

🎯

关键要点

  • 文章从.NET高级调试的角度分析Windows中线程上下文切换的问题。

  • 用户线程在操作系统层面上拥有两个线程栈:用户态栈和内核态栈。

  • 通过C#代码的Sleep(1)调用,可以观察到用户态和内核态的栈空间切换。

  • 用户态寄存器上下文在系统调用时会存放到_KTRAP_FRAME结构体中,该结构体位于内核态线程栈上。

  • 内核态线程上下文切换通过nt!KiSwapContext函数实现,保存现场的逻辑在此函数中。

  • Sleep(1)调用涉及到两块寄存器上下文,均保存在内核线程栈的InitialStack ~ KernelStack区间。

  • 此分析加深了对操作系统的理解,并解答了关于线程上下文切换的困惑。

➡️

继续阅读