有一个Channel 9 Video试图解释线程和任务之间的区别。我通常喜欢第9频道的视频,因为它们的技术准确性,但根据我的理解,这个视频的一些关键陈述是错误的。
以下是陈述:
以下是我的想法,我希望得到证实或证明:
调用堆栈的数量是可配置的。这样,对于32位进程,线程限制不是~1300但是高达12000。那些拥有SysInternals TestLimit副本的人可以试试:
D:\>testlimit -t -n 64
Testlimit v5.04 - test Windows limits
By Mark Russinovich - www.sysinternals.com
Creating threads with 64 KB stacks...
Created 12500 threads. Lasterror: 8
任务依赖于线程作为基础。这些线程是从线程池中获取的,但是,在使用它们之前,需要创建线程池的线程。 AFAIK,Mark Russinovich在Windows Internals书中也解释过,内核结构(_ETHREAD
)保存在内存中以供重用。这最大限度地减少了分配的开销,并将其减少到初始化。
我找不到我想要的确切位置,但在Windows Internals 6中,第41页上说明了第1部分:
[...]执行线程对象可能会或可能不会被释放。
由于任务依赖于线程作为技术实现,因此无论如何都会发生上下文切换。
如果我有2个线程,它们也可以在不同的处理器上执行。恕我直言,这是它的全部想法。
演讲者正在研究单核系统上的线程。恕我直言,在这种情况下,任务几乎没有任何好处。见4.。
见4.和5.。
幻灯片可能是正确的,但它没有显示实际原因。滑动它缺少导致上下文切换的~15ms时间片。如果线程需要等待结果,则只能使用Tasks减少开销。
在这种情况下,幻灯片的下半部分也是不正确的,因为Work 1的第一部分似乎是阻塞的,在这种情况下,Work 2只能执行。当工作2完成时,可以满足继续工作1的条件。只有在时间片内发生的所有事情,任务才有好处。
在任何情况下,迟早都会对任务进行上下文切换。
我已尝试在SO
的帮助下确认我的理解以上可能看起来像7个问题。我在一个地方问过他们,因为
答案 0 :(得分:1)
注意:Haven没有观看视频,完全基于OP中的信息。
调用堆栈的数量是可配置的。
可能,但不是真的相关,除非我们进入非常坚韧不拔的细节。
for .NET Tasks依赖于Threads作为基础。这些线程被采取 从线程池,但仍然是线程池的线程 需要在使用之前创建。
有点正确......虽然我们需要在抽象和实现之间保持清晰的界限。任务可以使用.Net中的Threadpool执行更正确。
任务代表了一个自包含代码段的想法,它通常可以与其他代码同时运行。线程是一种类似性质的操作系统实现。
由于Tasks依赖线程作为技术实现,因此无论如何都会发生上下文切换。
不正确的。虽然可以在线程上运行任务,并且可以进行上下文切换,但任务包含一层抽象,可提供更大的灵活性。
例如,要在线程之间交换执行,必须在硬件中发生上下文切换 。要在任务之间交换执行,不得进行此类硬件上下文切换。任务可以在不同的线程之间移动,进入休眠状态并在没有单个硬件上下文切换的情况下全部恢复。
如果我有2个线程,它们也可以在不同的线程上执行 处理器。恕我直言,这是它的全部想法。
正确。
演讲者正在讨论单核系统上的线程。恕我直言,在这种情况下任务几乎没有任何好处。
不正确的。任务在单线程系统上运行良好,因为它们只是一个抽象。此外,您可以在单个线程中运行许多任务,而无需任何硬件上下文切换,从而可能提高性能。
这里的主要概念问题似乎是认为Task = Thread。不是这种情况。任务是分解工作的概念性方法。线程是具有某些行为特征的类似想法的实现。虽然任务可以在封面下的线程上运行(不一定),但抽象允许它们以与硬件线程完全不同的方式运行。