首页 > 解决方案 > 如何告诉主管启动特定 gen_server 的 1000 个实例?

问题描述

作为解决计算密集型任务的一部分,我希望有 1000 个 gen_servers 执行小任务并更新全局数据库。如何在 erlang OTP 中实现这一点?在大多数示例中,主管只监督单个 gen_server。主管可以监督同一个 gen_server 的一千多个实例吗?

例如,假设我想找到一个极长数组的最大值,并且每个 gen_server 实例都应该在数组的一部分上创建工作并更新全局最小值。

标签: erlangerlang-supervisorgen-server

解决方案


有没有可能:是的。例如,您可以使用以下主管创建一个包含 1000 个进程的池:

-module (big_supervisor).

-export([start_link/0]).

-behaviour(supervisor).
-export([init/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, {}).

%% @private
init({}) ->
    Children = create_child_specs(1000),
    RestartStrategy = {one_for_one, 5, 10},
    {ok, {RestartStrategy, Children}}.

create_child_specs(Number) ->
    [{{child_process,X},{child_process, start_link, []},permanent, 5000, worker,[child_process]} || X <- lists:seq(1,Number)].

这是一个好的架构,我不知道。到目前为止,我发现了两种架构:

  • 一个有限且明确(按角色)的孩子
  • 具有一种流程工厂,根据需要使用simple_one_for_one策略和start_child/2 terminate_child/2功能动态创建任意数量的子代。

另请注意,如果您想生成进程,则主管不是强制性的。在您的解释中,似乎可以在非常有限的时间内创建进程,以便并行计算某些东西。在这种情况下有两个注释:

  • 产生更多的进程是不值得的,这些进程将有效地在您的 VM 上并行运行。
  • 一个例外是,如果要在每个流程中实现的工作都必须等待外部信息,例如外部数据库的返回。在这种情况下,产生更多进程可能会很有趣,最佳数量取决于外部访问限制。

推荐阅读