使用Actors池是否有意义?

时间:2009-12-31 16:49:30

标签: scala concurrency erlang actor

我只是在学习,并且非常喜欢Actor模式。我现在正在使用Scala,但我对建筑风格感兴趣,因为它在Scala,Erlang,Groovy等中使用。

我想到的情况是我需要同时做的事情,例如,让我们说“做一份工作”。

使用线程,我会创建一个线程池和一个阻塞队列,让每个线程轮询阻塞队列,并在进入和离开队列时处理它们。

对于演员来说,处理这个问题的最佳方法是什么?是否有意义创建一个演员池,并以某种方式向他们发送包含或作业的消息?也许与“协调员”演员?

注意 :我忘记提及案例的一个方面是:如果我想约束我的应用同时处理的作业数量该怎么办?也许配置设置?我认为游泳池可能很容易做到这一点。

谢谢!

3 个答案:

答案 0 :(得分:5)

池是一种在创建和拆除资源的成本很高时使用的机制。在Erlang中并非如此,因此您不应该维护池。

您应该根据需要生成流程,并在完成后销毁它们。

答案 1 :(得分:4)

有时,限制在大型任务列表上同时运行的工作进程数是有意义的,因为生成的流程完成涉及资源分配的任务。至少进程耗尽内存,但它们也可以保持打开的文件和/或套接字,这些文件和/或套接字往往只限于数千个,并且一旦用完就会失败并且不可预测。

要拥有一个拉动任务池,可以生成要求执行任务的 N 链接进程,一方面可以生成一个可以spawn_monitor的函数。一旦受监控的流程结束,他们就会回来完成下一个任务。具体需求推动了细节,但这是一种方法的概述。

我让每个任务产生一个新进程的原因是进程确实有一些状态,并且开始一个干净的平板是很好的。这是一种常见的微调,可以将流程的最小堆大小调整为最小化其生命周期内所需的GC数量。它也是一个非常有效的垃圾收集,可以为进程释放所有内存,并为下一个任务启动一个新内存。

使用两次这样的进程数量会不会感到奇怪?这是Erlang编程中需要克服的感觉。

答案 2 :(得分:2)

所有案例都没有最好的办法。决定取决于工作的数量,持续时间,到达时间和所需的完成时间。

仅仅产生演员和使用游泳池之间最明显的区别是,在前一种情况下,您的工作几乎会同时完成,而在后一种情况下,完成时间将及时传播。平均完成时间虽然相同。

使用actor的优点是编码简单,因为它不需要额外的处理。权衡是你的演员将争夺你的CPU核心。无论您使用何种编程范例,您都无法拥有比CPU核心(或HT,无论如何)更多的并行作业。

举个例子,假设您需要执行100'000个工作,每个工作需要一分钟,结果将在下个月完成。你有四个核心。你会产生100,000名演员,他们每人争夺一个月的资源,或者你只是将你的工作排队,并且一次执行四次?

作为一个反例,想象一下在同一台机器上运行的Web服务器。如果您有五个请求,您是希望在T时间内为四个用户服务,在2T中服务一个用户,还是在1.2T时间内为所有五个用户服务?