我前几天遇到了一个问题,我将工人NumberOfWorkers
调整为一个嘲笑数字,期望看到吞吐量相等的跳跃。我只能看到5名工人一次做任何工作。想出魔术帽是Max Parallelism选项,默认值是5。
我的假设是1名工作人员等于1个帖子。
MaxParallelism
和branch1(E,X) :- quality(E,X), member(X, [a,b,c]).
branch2(E,X) :- quality(E,X), member(X, [d,e,f]).
选项的目的或关系是什么?
答案 0 :(得分:2)
虽然我意识到它可能不是很明显,但它实际上非常简单。
“工作人员数量”是此特定总线实例中的工作线程数,这是完全正确的。
但由于Rebus中的所有内容现在都是async
,如果该作品可以await
,那么单个工作人员可以同时执行大量的工作。
因此 - 为了避免做太多工作 - 引入了“最大并行度”概念,它为并行处理的消息数量设置了全局最大上限。
要使用哪些值取决于您要执行的工作类型。以下是一些合理的设置:
.SetNumberOfWorkers(2).SetMaxParallelism(20)
.SetNumberOfWorkers(5).SetMaxParallelism(5)
(尽管在这种情况下将并行度设置得更高不会影响任何内容).SetNumberOfWorkers(15).SetMaxParallelism(15)
(再次:将并行度设置得更高不会影响这种情况下的任何内容)正如您已经正确观察到的那样,由于并行性设置对可以并行处理的消息数设置了绝对上限,因此将并行度设置为低于线程数是没有意义的。
编辑:我已将this page添加到维基 - 感谢您让我意识到这个概念没有在任何地方解释:)
答案 1 :(得分:0)
我查看了Rebus代码,似乎混合了普通线程和线程池线程-工作者本身就是普通线程,但是它产生了多个TPL任务,并且不等待该任务完成就立即尝试生成另一个消息(如果接收到消息及其处理确实是异步的,则可以执行此操作)。阻止它产生无限数量的任务的原因是:
var parallelOperation = _parallelOperationsManager.TryBegin();
if (!parallelOperation.CanContinue())
{
_backoffStrategy.Wait();
return;
}
parallelOperationsManager阻止它产生比异步任务的MaxParallelism更多的信息。在尝试生成新Task之前,它使用Semaphore计数器。如果计数器达到MaxParalleism的数量,则线程将被Thread.Sleep阻塞一小段时间,以便有时间完成正在运行的任务,减少信号量计数器,并允许产生新的Task(读取后端队列并处理消息)。
因此从本质上讲-工人数量-是普通的NET Framework线程的数量,而MaxParallelism是任务的最大数量(实际上不是线程池线程的数量,但是它们可以使用线程池进行异步执行< / em>) 没有MaxParallelism约束,单个Worker(普通线程)可以生成数百万个IO绑定的异步任务,但无论如何只能处理单个同步任务。
如果作业是完全同步的,则它将在普通线程上进行处理,并且如果作业包含等待异步操作的代码,则直到异步代码这一点的作业将在普通线程上执行,之后在线程池线程上等待。