【问题标题】:What's C# threading type?什么是 C# 线程类型?
【发布时间】:2013-02-12 03:55:09
【问题描述】:

在三种类型的线程(内核级、用户级和混合)之间,C#(或更一般的 .NET)使用哪种类型?

【问题讨论】:

标签: c# .net multithreading winapi


【解决方案1】:

核心线程 (1 : 1)

术语“内核线程”可以用来指完全在内核空间中运行的实际线程,也可以指由内核调度的用户空间线程。术语“内核支持”线程是指后者,即在用户空间中运行但由内核促进的线程,这通常意味着内核调度它们。

内核线程具有特权,可以访问用户模式线程无法访问的内容。看看维基百科上的“Ring (Computer Security)”。在 Windows 上,用户模式对应 Ring 3,内核模式对应 Ring 0。

用户级线程 (N : 1)

“用户级线程”通常是指对用户空间可见的线程。也就是说,您在调用线程标准的“创建线程”函数时创建的内容。通常,术语“用户级线程”用于表示由应用程序代码创建的线程,而不管它是如何由系统实现的。它可能是一个纯用户空间线程,几乎没有内核支持,也可能是内核调度的线程。

混合线程(M : N)[维基百科]

M:N 将 M 数量的应用程序线程映射到 N 数量的内核实体或“虚拟处理器”上。这是内核级(“1:1”)和用户级(“N:1”)线程之间的折衷。一般来说,“M:N”线程系统比内核或用户线程更复杂,因为需要更改内核和用户空间代码。在 M:N 实现中,线程库负责在可用的可调度实体上调度用户线程;这使得线程的上下文切换非常快,因为它避免了系统调用。

.Net 线程是用户级线程,使用 Win32 API 并将其封装为一个不错的框架!


可以找到更多细节:

【讨论】:

  • @MichaelPerrenoud - 问题本身就是一个班轮迈克尔!
  • 所以你说.net的线程类,使用用户级线程。混合线程怎么样?
  • 感谢您的努力,我的意思是当我从 .net 中的 Thread 类创建实例时,哪些模型有效?如果我创建多个 Thread 类实例,混合模型有效或用户级?
  • 这样说吧。如果我运行一个创建 1000 个(额外)线程的 C# 应用程序,任务管理器会显示该应用程序有 1001 个线程。
【解决方案2】:

这不取决于 C# 本身,而是取决于运行时 - CLR。

.Net 可以考虑支持两种模式:

  • 仅限用户空间调度(或Windows UMS)。在这种模式下,一个用户态线程可以执行上下文切换到另一个用户模式线程,而无需实际更改内核线程。这种模式增加了很多编码开销,但在内核级上下文切换中节省了宝贵的 10-20 微秒。
  • 混合模型(目前最流行)。在此模型中,托管代码需要访问内核,例如读取文件。通过一组 API,代码执行从用户级 .NET 调用到 Windows API,再到内核、驱动程序、HAL 层和物理驱动器。并通过调用堆栈返回获取数据。如果线程调度程序启动了上下文切换,那么用户线程和内核线程就会发生变化。

不允许直接内核模式线程,因为托管代码没有在内核模式下运行的特权。它只能调用Windows API,然后切换到内核模式。


如果您使用ThreadTaskThreadPool - CLR 使用混合模型。使用混合模型是因为 CLR 创建托管对象来表示这些类。任何托管代码都在用户空间中运行。但是,每个不是作为 fibber 创建的线程(见下文),无论是否在线程池中,都具有底层内核数据结构。内核数据结构用于保存线程的内核状态——内核线程id、创建和退出时间、进程id、启动线程地址、安全访问令牌、十几个定时器、CPU寄存器、内核堆栈等。所有这些都需要在运行期间更新上下文切换,但我们只需要大约 10-20 * 10^-6 秒。

如果您在 Ums 组 C++ 调用(如 CreateUmsThreadContextUmsThreadYield 和许多其他调用)周围使用托管包装器 - CLR 会尝试使用 UMS 模式。但这仅适用于您专门手动操作的少数线程。您的应用程序仍将使用混合模型,在用户模式下,将在彼此之间手动生成一些手动选择的线程(纤维)。但即使在这种模式下,操作系统任务调度程序也会在某些时候启动内核线程切换,因此您不会永远被困在执行 UMS 调度线程。

为了完整性,

  • 内核模式调度是一种非常低级的机制,只能从内核访问。这意味着你只能使用它,如果你开发操作系统内部或某种驱动程序。这样的调度很难使用,任何错误和整个操作系统被冻结/卡住/崩溃/BSODed或转换到任何其他不可预测的状态。内核级线程需要大量的开发和测试工作。例如,Windows 任务调度程序或内存管理服务使用内核模式调度。您能想象一下编写这些组件需要多少时间才能使它们在高度多线程的环境中保持稳定?

【讨论】:

  • 我认为 .net 使用混合模型,我的意思是当我从 .net 中的 Thread 对象创建实例时,这些模型中的哪一个有效?
  • 您可以为我们提供一个参考吗?
猜你喜欢
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2013-05-27
  • 2011-07-01
  • 2011-07-01
相关资源
最近更新 更多