.NET线程是否与操作系统线程不同?

  1. .NET线程是轻量级用户模式线程还是内核模式操作系统线程?

  2. 另外,保留SQL Server,.NET线程和操作系统线程之间是否存在一对一的对应关系?

我也很感兴趣因为Thread类有一对名为EndThreadAffinityEndThreadAffinity的对称方法,其文档巧妙地暗示.NET线程是真实操作系统线程上的轻量级抽象。

此外,我刚才读到一些堆栈溢出线程本身,微软试图在CLR中保持这种分离,就像SQL Server一样。 我记得有一些项目正在使用Fiber API来实现这个目的,但我不能说我理解了我所读到的所有细节。

我想要一些关于这个主题的更详细的文献,比如.NET线程的内部结构与Windows创建的线程的内部结构相比。 虽然有很多关于Windows创建的线程结构的信息,但Jeffrey Richter的高级Windows编程书是其中一个来源,例如,我找不到任何专门讨论.NET线程内部结构的文献。

有人可能会争辩说,这些信息可以在.NET源代码中找到,现在可以公开获得,或者使用反汇编程序,如Reflector或IL Spy,但是我没有看到任何代表线程控制块(TCB)和程序的信息。计数器(PC)和堆栈指针(SP)或线程的等待队列,或线程当前在Thread类中成员的队列列表。

我在哪里可以读到这个? 文档中是否提到了它的任何内容? 我已经从MSDN上阅读了所有这些页面,但他们似乎没有提到它。

.NET的线程确实是抽象,但你基本上可以认为它们与OS线程几乎相同。 有一些关键的差异,特别是在垃圾收集方面,但绝大多数程序员(读:不太可能启动WinDBG的程序员)没有function差异。

有关详细信息,请阅读此内容

在决定如何进行并发之前,了解预期性能和预期并发性质的一些想法非常重要。 例如,.NET是一个虚拟机,因此模拟了并发性。 这意味着开始执行的开销比直接OS线程更多。

如果您的应用程序打算按需具有重要的并发性,那么.NET任务或线程(甚至ThreadPool)将很难创建并开始执行。 在这种情况下,您可能会受益于Windows操作系统线程。 但是,您将需要使用非托管线程池(除非您喜欢我并且您更喜欢编写自己的线程池)。

如果根据需要启动不确定数量的线程的性能不是设计目标,那么您应该考虑.NET并发性。 原因是编程更容易,您可以利用影响编程语言内置并发性的关键字。

为了正确看待这个问题,我编写了一个测试应用程序来测试运行在不同并发执行单元中的算法。 我在我自己的非托管线程池,.NET任务,.NET线程和.NET ThreadPool下运行测试。

并发设置为512,意味着将尽快调用512个并发执行单元,我发现.NET在起始块上的速度非常慢。 我在几个系统上运行了测试,从具有16GB RAM的i5 4核桌面到Windows Server 2012 R2,结果是相同的。

我捕获了已完成的并发执行单元数,每个单元启动的时间以及CPU核心利用率。 每次测试的持续时间为30秒。

所有测试都导致CPU核心利用率均衡(与某些人的观点相反)。 但是,任何.NET都会失败。 在30秒内……

.NET任务和线程(ThreadPool)完成了34个任务,平均启动时间为885毫秒

所有512个OS线程都以59ms的平均启动时间运行完成。

无论人们怎么说,从调用API开始执行单元和实际执行单元的路径在.NET中要长得多。