简体   繁体   English

第 9 频道对任务与线程的解释是否正确?

[英]Is the Channel 9 explanation of Tasks vs. Threads correct?

There's a Channel 9 Video that attempts to explain the difference between Threads and Tasks.有一个Channel 9 Video试图解释线程和任务之间的区别。 I usually like the Channel 9 videos for their technical accuracy, but from my understanding, this one gets some of the key statements wrong.我通常喜欢第 9 频道的视频,因为它们的技术准确性,但据我所知,这个视频的一些关键陈述是错误的。

Here are the statements:以下是声明:

  1. @~1:48 to ~2:30: Threads are expensive in memory and time. @~1:48 到 ~2:30:线程在内存和时间上都很昂贵。 Each thread gets 1 MB of user mode stack.每个线程获得 1 MB 的用户模式堆栈。
  2. @~2:30 to 2:37: It also takes time to create threads. @~2:30 到 2:37:创建线程也需要时间。 Time to allocate the data structures and initialize them.是时候分配数据结构并初始化它们了。
  3. @~2:38 to 2:45: Context switching also takes time. @~2:38 到 2:45:上下文切换也需要时间。
  4. @~2:58 to 3:23 and 3:48 to : Tasks make use of a multi-core system [...] So when you do compute, you're using multiple cores. @~2:58 到 3:23 和 3:48 到:任务使用多核系统 [...] 因此,当您进行计算时,您使用的是多核。
  5. @~5:02 to 5:30: Threads run on a single core and context switching happens a lot. @~5:02 到 5:30:线程在单核上运行,上下文切换发生很多。
  6. @~5:40 to 5:51: Threads have different ways to execute. @~5:40 到 5:51:线程有不同的执行方式。 They execute on multiple cores.它们在多个内核上执行。
  7. @~6:20 to 6:30: As you see here in the diagram, Threading has overhead. @~6:20 到 6:30:正如您在图中看到的,线程处理有开销。

And here are my thoughts that I'd like to be confirmed or disproven:以下是我想确认或否定的想法:

  1. The amount of call stack is configurable.调用堆栈的数量是可配置的。 That way, the thread limit is not ~1300 but up to 12000 for a 32 bit process.这样,对于 32 位进程,线程限制不是 ~1300,而是高达 12000。 Those who have a copy of SysInternals TestLimit available can try it:那些拥有 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

    The stack size is also exposed in the Thread Constructor for .NET堆栈大小也在.NET线程构造函数中公开

  2. Tasks rely on Threads as a basis.任务依赖于线程作为基础。 Those threads are taken from the thread pool, but nevertheless, the threads of the thread pool need to be created before they can be used.那些线程是从线程池中取出来的,但是,线程池的线程需要先创建后才能使用。 AFAIK, Mark Russinovich also explained in the Windows Internals book, that the kernel structure ( _ETHREAD ) is kept in memory for reuse. AFAIK,Mark Russinovich 在 Windows Internals 一书中也解释过,内核结构( _ETHREAD )保存在内存中以供重用。 This minimizes the overhead of allocation and reduces it to initialization.这最大限度地减少了分配的开销并将其减少到初始化。

    I didn't find the exact place I was looking for, but in Windows Internals 6, part 1 it says on page 417:我没有找到我正在寻找的确切位置,但在 Windows Internals 6,第 1 部分中,它在第 417 页上说:

    [...] the executive thread object might or might not be deallocated. [...] 执行线程对象可能会或可能不会被释放。

  3. Since Tasks rely on threads as the technical implementation, context switching occurs in any case.由于 Task 依赖于线程作为技术实现,因此无论如何都会发生上下文切换。

  4. If I have 2 threads, they can also be executed on different processors.如果我有 2 个线程,它们也可以在不同的处理器上执行。 IMHO that's the whole idea of it.恕我直言,这就是它的全部想法。

  5. The speaker is taslking about threads on a single core system.演讲者正在讨论单核系统上的线程。 IMHO, tasks will have almost no benefit in that case as well.恕我直言,在这种情况下,任务也几乎没有任何好处。 See 4.)见 4。)

  6. See 4. and 5.)见 4. 和 5。)

  7. The slide may be correct, but it does not show the actual reason for that.幻灯片可能是正确的,但它没有显示出真正的原因。 The slide it missing the ~15 ms time slices which cause the context switching.该幻灯片缺少导致上下文切换的 ~15 ms 时间片。 The overhead can only be reduced using Tasks if the thread needs to wait for a result.如果线程需要等待结果,则只能使用任务来减少开销。

    In that case, the lower part of the slide is incorrect as well, because the first part of Work 1 seems to be blocking, in which case Work 2 could be executed only.在这种情况下,幻灯片的下半部分也不正确,因为工作 1 的第一部分似乎被阻塞,在这种情况下,工作 2 只能执行。 When Work 2 finishes, the condition to continue with Work 1 might be fulfilled.当工作 2 完成时,可能满足继续工作 1 的条件。 Only if all that occurs within a time slice, Tasks have a benefit.只有当所有这些都发生在一个时间片内时,任务才有好处。

    In any case, a context switch will occur with Tasks as well, sooner or later.无论如何,任务也迟早会发生上下文切换。

I have tried confirming my understanding with the help of these questions on SO我已经尝试在 SO 上的这些问题的帮助下确认我的理解

Above might seem like 7 individual questions.以上可能看起来像是 7 个单独的问题。 I asked them all in one place because我在一处询问了他们,​​因为

  • the all have their source in one video在一个视频中都有他们的来源
  • some questions depend on each other有些问题相互依赖
  • it's IMHO more important to find the information in one place than following the SO rule of asking one question at a time.恕我直言,在一个地方找到信息比遵循一次提出一个问题的 SO 规则更重要。

Note: Haven't watched the video, based purely on the info in OP.注意:还没有观看视频,纯粹基于 OP 中的信息。

The amount of call stack is configurable.调用堆栈的数量是可配置的。

Probably, but not really relevant unless we're getting into very gritty details.可能,但不是真正相关,除非我们进入非常详细的细节。

for .NET Tasks rely on Threads as a basis.对于 .NET 任务依赖于线程作为基础。 Those threads are taken from the thread pool, but nevertheless, the threads of the thread pool need to be created before they can be used.那些线程是从线程池中取出来的,但是,线程池的线程需要先创建后才能使用。

Somewhat correct... though we need to keep a very clear demarcation between abstraction and implementation.有点正确……尽管我们需要在抽象和实现之间保持非常清晰的界限。 Tasks can use the Threadpool in .Net for execution is more correct.任务可以使用.Net中的Threadpool来执行更正确。

Tasks represent the idea of a self-contained section of code that (usually) can run concurrently of other code.任务代表了一个自包含代码段的想法,它(通常)可以与其他代码并发运行。 Threads are an OS implementation of similar nature.线程是类似性质的操作系统实现。

Since Tasks rely on threads as the technical implementation, context switching occurs in any case.由于 Task 依赖于线程作为技术实现,因此无论如何都会发生上下文切换。

Incorrect.不正确。 While Tasks can be run on threads, and context switching can occur, Tasks contain a layer of abstraction that provides more flexibility.虽然任务可以在线程上运行,并且可以发生上下文切换,但任务包含一个提供更多灵活性的抽象层。

For example, to swap execution between threads, a context switch must occur in the hardware.例如,要在线程之间交换执行,必须在硬件中进行上下文切换。 To swap execution between tasks, no such hardware context switch must occur.要在任务之间交换执行,不必发生此类硬件上下文切换。 Tasks can be moved between different threads, put to sleep and restored all without a single hardware context switch.任务可以在不同线程之间移动、休眠和恢复,无需单个硬件上下文切换。

If I have 2 threads, they can also be executed on different processors.如果我有 2 个线程,它们也可以在不同的处理器上执行。 IMHO that's the whole idea of it.恕我直言,这就是它的全部想法。

Correct.正确的。

The speaker is talking about threads on a single core system.演讲者正在谈论单核系统上的线程。 IMHO, tasks will have almost no benefit in that case as well.恕我直言,在这种情况下,任务也几乎没有任何好处。

Incorrect.不正确。 Tasks run well on single threaded systems as they are simply an abstraction.任务在单线程系统上运行良好,因为它们只是一个抽象。 Furthermore you can run many tasks in a single thread without any hardware-context switches, potentially increasing performance.此外,您可以在单个线程中运行多个任务,而无需任何硬件上下文切换,这可能会提高性能。


The main conceptual issue here seems to be the thinking that Task = Thread.这里的主要概念问题似乎是 Task = Thread 的想法。 This is not the case.不是这种情况。 A task is a conceptual way of breaking down work.任务是分解工作的概念方式。 A thread is a implementation of a similar idea with certain behavioral characteristics.线程是具有某些行为特征的类似想法的实现。 While tasks can run on threads under the covers (not necessarily) the abstraction allows them to behave in a very different way than a hardware thread.虽然任务可以在幕后线程上运行(不一定),但抽象允许它们以与硬件线程非常不同的方式运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM