使用Actors池是否有意义?

Avi*_*lax 8 concurrency erlang scala actor

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

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

使用线程,我将创建一个线程池和一个阻塞队列,并让每个线程轮询阻塞队列,并在进入和离开队列时处理作业.

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

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

谢谢!

Gor*_*rie 5

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

您应该根据需要生成进程,并在完成它们时将其销毁.

  • @Avi:我想你需要在这里做出区分."池"通常指的是(至少对我来说)实际上保留了actor /进程并重用它们.在Erlang你不需要这样做,你可以扔掉它们并产生新的.当然,您可以实现"全局计数器"(以服务器进程的形式,在ets表中等),您可以在生成另一个作业进程之前进行轮询.事实上,你确实需要这样的设施来实现负载控制...... (3认同)

Chr*_*ian 4

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

为了拥有一个拉动任务池,我们可以生成N 个请求任务的链接进程,并为它们提供一个可以 spawn_monitor 的函数。一旦受监控的进程结束,他们就会返回执行下一个任务。特定需求驱动细节,但这只是一种方法的概要。

我让每个任务产生一个新进程的原因是进程确实有一些状态,并且从头开始是很好的。这是一种常见的微调,用于设置进程的最小堆大小,以最大程度地减少其生命周期内所需的 GC 数量。这也是一种非常有效的垃圾收集,可以释放进程的所有内存,并为下一个任务启动新的内存。

使用两倍数量的进程是不是感觉很奇怪?这是你在 Erlang 编程中需要克服的感觉。