c#线程类型是什么?

本文关键字:是什么 类型 线程 | 更新日期: 2023-09-27 18:01:18

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

c#线程类型是什么?

内核线程(1:1)

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

内核线程有特权,可以访问用户模式线程不允许访问的东西。看看"Ring(计算机安全)"&;在维基百科上。在Windows上,用户模式对应Ring 3,而内核模式对应Ring 0。

用户级线程(N: 1)

"用户级threads"通常表示对用户空间可见的线程。也就是说,当你调用线程标准" create thread "时,你所创建的东西函数。一般来说,术语"用户级线程"用于表示由应用程序代码创建的线程,而不管系统如何实现它。它可以是一个纯用户空间线程,几乎没有内核支持,也可以是一个由内核调度的线程。

Hybrid Threading (M: N) [WikiPedia]

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

。Net线程是使用Win32 API的用户级线程,并将其封装为一个漂亮的框架!


更多细节可以找到:

  • 线程(计算)
  • 内核线程vs内核支持线程vs用户级线程
  • 用户线程和内核线程线程是内核对象吗?

这不是c#本身的问题,而是运行时CLR的问题。

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

  • User-land only调度(或Windows UMS)。在这种模式下,一个用户模式线程可以执行上下文切换到另一个用户模式线程,而无需实际更改内核线程。这种模式增加了大量的编码开销,但在内核级上下文切换中节省了宝贵的10-20微秒。
  • 混合模式(目前最流行)。在这个模型中,托管代码需要访问内核,比如读取文件。通过一组API,代码执行从用户端。net调用传递到Windows API、内核、驱动程序、HAL层和物理驱动器。然后通过调用栈返回获取数据。如果线程调度器启动了上下文切换,那么用户线程和内核线程将被更改。

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


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

如果你在Ums一组c++调用(如CreateUmsThreadContext, UmsThreadYield和许多其他)周围使用托管包装- CLR尝试使用Ums模式。但这仅针对您专门手动操作的少数线程。您的应用程序仍将使用混合模式,在用户模式下,只有几个手工挑选的线程(光纤)将在彼此之间手工产生。但是,即使在这种模式下,在某些时候操作系统任务调度程序将启动一个内核线程切换,所以您不会永远卡住执行UMS调度线程。

完整性、

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