你如何在Erlang中调节并发/进程性能?

4
假设我需要读取一个包含许多大型XML文件的目录,并对其进行解析,接着通过网络将它们发送到某个服务,最后再将响应写入磁盘。如果是Java或C++等语言,可能会像这样做(希望这有意义):
(File read & xml parsing process) -> bounded-queue -> (sender process) -> service

service -> bounded-queue -> (process to parse result and write to disk)

然后,我会为每个进程分配适当数量的线程。这样,我可以将每个进程的并发限制在其最佳值,并且有界队列将确保不会出现内存短缺等问题。
但是,在编写Erlang代码时应该怎么做呢?我想我可以在一个函数中实现整个流程,然后迭代目录并尽可能快地生成这些“从头到尾”的进程。虽然这听起来不太理想,因为如果XML解析时间比读取文件时间长等,则应用程序可能会因为一次性在内存中拥有许多XML文档而导致内存短缺等问题,而且您无法保持并发处于最佳水平。例如,如果“服务”在并发为4时最有效,则使用巨大的并发处理它将非常低效。
那么,Erlang程序员应该如何处理这种情况?即什么是Erlang中固定线程池和有界队列的替代品?
3个回答

3
你可以在Erlang中自行运行进程池,但这是一种内存使用不佳的方法,因为它没有考虑正在读取的XML数据的大小(或者说总进程使用的内存)。

我建议您实现整个工作流程在一个函数库中,并生成执行此工作流程的进程。添加一个检查内存使用情况的步骤,它将查看要读取的数据大小和可用内存(提示:使用 memsup)。


谢谢你的回答!如果我的问题不是关于内存,例如我想要在特定并发下与服务进行通信,那么使用进程池是否是一个好选择?编辑:我想我从DefLog那里得到了答案。 - Enno Shioji
他基本上得出了和我一样的结论。而且基于固定进程数量的限制并没有实际意义,这并不能告诉你什么(除非这是您确切的要求:同时不超过N个并发任务)。 - Adam Lindberg

3

除了及时处理所有队列,没有真正的方法来限制进程的队列大小。最好的方法是在生成新进程之前检查可用资源并等待它们足够。因此,如果您担心内存,请在生成新进程之前检查内存。如果是磁盘空间,则检查磁盘空间等。

限制生成的进程数量也是可能的。一个简单的构造是:

pool(Max) -> 
    process_flag(trap_exit, true),
    pool(0, Max);
pool(Current, Max) ->
    receive
        {'EXIT', _, _} -> 
            pool(Current - 1, Max);
        { work, F, Pid} when Current < Max -> 
            Pid ! accepted,
            spawn_link(F),
            pool(Current + 1, Max);
        { work, _, Pid} -> 
            Pid ! rejected,
            pool(Current, Max);
    end.

这是一个简单的流程图,说明一个进程如何限制它所生成的进程数量。然而,更好的方法是基于真实原因进行限制,而不是仅仅依靠一个人为设定的数字。

1

我建议您使用事件驱动的范例。

想象一下,您启动了带有文件名列表的OTP gen_server。

  1. gen_servers检查资源并在允许的情况下生成下一个工作进程,从列表中删除文件名并将其传递给工作进程。

  2. 工作进程处理文件并在准备就绪时向gen_server发送消息(或者您可以捕获EXIT)。

  3. gen_server接收此类消息并执行步骤1,直到文件列表为空为止。

因此,工作进程负责繁重的工作,而gen_server控制流程。

您还可以创建分布式系统,但这需要更复杂的操作,因为您需要在每台计算机上生成中间的gen_servers,并查询它们是否有可用的资源,然后根据回复选择哪台计算机应该处理下一个文件。您可能需要像NFS这样的东西来避免发送长消息。

如果需要更多并发性,可以进一步拆分工作进程。


这是否意味着gen_server内部有某种信号量并集中控制并发等? - Enno Shioji
我不确定Erlang的内部实现,但是它的消息传递确实类似于具有无限队列容量(生产者永远不会阻塞)的消费者/生产者模型,这通常使用信号量来实现。 - Victor Moroz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接