C# 中的任务并行性 (TPL) 和任务调度
根据 Microsoft (链接),有两种方法可以启动任务:隐式和显式。
假设我在主线程中创建了 4 个不同的任务,称为任务 1、任务 2、任务 3 和任务 4。
case1:我在主线程中显式运行它们:
task1.Start();
task2.Start();
task3.Start();
task4.Start();
case2:我在主线程中使用 Parallel.Invoke 方法隐式运行它们:
Parallel.Invoke(task1, task2, task3, task4);
我注意到的唯一区别是在 case2 中,主线程挂起直到 Invoke() 返回。
我的问题是关于任务调度程序的。 任务调度程序在 case1 和 case2 中的 4 个任务在调度方面的表现是否不同,或者它们是完全等效的?
在我上面提到的同一链接中,我们读到:
在后台,任务会排队到线程池中,该线程池已被 通过算法(如爬山)来确定和增强 调整到最大化吞吐量的线程数。这使得 任务相对轻量级,您可以创建其中许多任务来 启用细粒度并行性。为了补充这一点,广为人知的 采用工作窃取算法来提供负载平衡。
According to Microsoft (link), there are two ways to start a task: Implicit and Explicit.
Assume that I created 4 different tasks in main thread called task1, task2, task3 and task4.
case1: I run them all, explicitly in main thread:
task1.Start();
task2.Start();
task3.Start();
task4.Start();
case2: I run them implicitly using Parallel.Invoke method in main thread:
Parallel.Invoke(task1, task2, task3, task4);
The only difference I noticed is that in case2, the main thread suspends until Invoke( ) returns.
My question is about the Task scheduler.
Does the task scheduler behave 4 tasks in case1 and case2 differently in terms of scheduling or they are completely equivalent ?
in the same link I have mentioned above we read:
Behind the scenes, tasks are queued to the ThreadPool, which has been
enhanced with algorithms (like hill-climbing) that determine and
adjust to the number of threads that maximizes throughput. This makes
tasks relatively lightweight, and you can create many of them to
enable fine-grained parallelism. To complement this, widely-known
work-stealing algorithms are employed to provide load-balancing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Parallel 团队的这篇博文应该回答你的一些问题。
简短的回答:对于任务,您必须在主线程上执行 Task::WaitAll(...) 以防止退出,因为 Parallel::Invoke 实际上会为您处理这个问题。除此之外,没有别的,因为在 Parallel::Invoke 下使用相同的 TPL 基础设施。
This blog post from the Parallel team should answer some of your questions.
Short answer: with Tasks you will have to do a Task::WaitAll(...) on your main thread to prevent from exiting where as Parallel::Invoke will actually take care of this for you. Beyond that, nothing else because the same TPL infrastructure is used under Parallel::Invoke.