我手头的任务是读取大文件的行,对其进行处理并返回有序的结果。
我的算法是:
因此基本上不需要工人之间的沟通。
我的问题:
erlang message passing architecture
最佳答案
当您不知道时,最简单的方法是让用户决定。这意味着您可以决定生成
N
工人,并在他们之间分配工作,等待回音。如果您不喜欢它的运行方式,请在更改N
的同时重新运行该程序。比较棘手的方法是对大量时间进行基准测试,选择您认为有意义的最大值,然后将其粘贴到池库中(如果您愿意;某些池用于预分配的资源,有些用于可调整的量),并寻求一种“一刀切”的解决方案。
但是实际上,没有简单的“最佳内核数量”。您可以在50个进程上运行它,也可以在65,000个进程上运行它。如果任务令人尴尬地是并行的,则VM应该能够充分利用其中的大部分资源,并且无论如何都要饱和内核。
--
棘手的是,实际上像
pread/2-3
这样的功能需要字节偏移量。您的问题的措词使您担心文件的行数。因此,您移交给工作人员的字节偏移量可能最终会跨越一行。如果您的代码块以my
中的this is my line\nhere it goes\n
单词结尾,则一个工作人员将看到自己的行不完整,而另一个工作人员将仅报告my line\n
,而缺少先前的this is
。通常,这种烦人的东西会导致您让第一个进程拥有文件并进行筛选,而只是将一些文本交予工作人员处理;然后,该过程将充当某种协调者。
该策略的一个不错的方面是,如果主进程知道作为消息发送的所有内容,那么它也知道何时收到了所有响应,因此很容易知道何时返回结果。如果一切都不相交,则您必须信任初学者和工人,以告诉您“我们都失业了”,作为一组独特的独立消息要知道。
在实践中,您可能会发现,最有用的是知道有关文件操作的操作,这些操作可以帮助您的硬件生存,而不是“有多少人可以一次读取文件”。只有一个硬盘(或SSD),无论如何所有数据都必须经过它。并行性最终可能会限制在那里的访问。
--
一个更实际的,性能卓越的程序将使用很少的,很小的消息。
有趣的是,您的问题本质上是基于数据的。因此,您可以执行以下操作:
raw
或ram
模式读取文件。其他模式使用中间人进程来读取和转发数据(如果在群集的Erlang节点中通过网络读取文件,这将很有用); raw
和ram
模式将文件描述符直接提供给调用过程,并且速度更快。 我希望这有帮助。
附言您可以首先尝试真正简单的东西:
{ok, Bin} = file:read_file(Path)
一次读取整个文件,并使用binary:split(Bin, <<"\n">>, [global])
){ok, Io} = file:open(File, [read,ram])
,然后在文件描述符上反复使用file:read_line(Io)
{ok, Io} = file:open(File, [read,raw,{read_ahead,BlockSize}])
,然后在文件描述符上反复使用file:read_line(Io)
rpc:pmap({?MODULE, Function}, ExtraArgs, Lines)
以自动并行运行所有内容(它将每行生成一个进程)lists:sort/1
。 然后,如果您认为有问题,则可以从那里优化每个步骤。
关于concurrency - erlang流程和消息传递体系结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30754165/