这些是我在erlang中的第一步,很抱歉这个新手问题:)我为每个redis请求提供了一个新的erlang进程,这不是我想要的("太多的过程"在32k Erlang过程中),但是如何将过程的数量限制为例如最大限度。16?
-module(queue_manager).
-export([add_ids/0, add_id/2]).
add_ids() ->
{ok, Client} = eredis:start_link(),
do_spawn(Client, lists:seq(1,100000)).
do_spawn(Client, [H|T]) ->
Pid = spawn(?MODULE, add_id, [Client, H]),
do_spawn(Client, T);
do_spawn(_, []) -> none.
add_id(C, Id) ->
{ok, _} = eredis:q(C, ["SADD", "todo_queue", Id]).
尝试使用ERLANG pg2
模块。它允许您创建过程组,并提供一个API,以获取组中的"最接近"(或随机)PID。
这是eredis
客户端的过程组的示例:
-module(redis_pg).
-export([create/1,
add_connections/1,
connection/0,
connections/0,
q/1]).
create(Count) ->
% create process group using the module name as the reference
pg2:create(?MODULE),
add_connections(Count).
% recursive helper for adding +Count+ connections
add_connections(Count) when Count > 0 ->
ok = add_connection(),
add_connections(Count - 1);
add_connections(_Count) ->
ok.
add_connection() ->
% start redis client connection
{ok, RedisPid} = eredis:start_link(),
% join the redis connection PID to the process group
pg2:join(?MODULE, RedisPid).
connection() ->
% get a random redis connection PID
pg2:get_closest_pid(?MODULE).
connections() ->
% get all redis connection PIDs in the group
pg2:get_members(?MODULE).
q(Argv) ->
% execute redis command +Argv+ using random connection
eredis:q(connection(), Argv).
这是上述模块的示例:
1> redis_pg:create(16).
ok
2> redis_pg:connection().
<0.68.0>
3> redis_pg:connection().
<0.69.0>
4> redis_pg:connections().
[<0.53.0>,<0.56.0>,<0.57.0>,<0.58.0>,<0.59.0>,<0.60.0>,
<0.61.0>,<0.62.0>,<0.63.0>,<0.64.0>,<0.65.0>,<0.66.0>,
<0.67.0>,<0.68.0>,<0.69.0>,<0.70.0>]
5> redis_pg:q(["PING"]).
{ok,<<"PONG">>}
您可以使用连接池,例如eredis_pool。这是一个类似的问题,对您来说可能很有趣。
您可以使用主管启动每个新过程(例如,您应该使用simple_one_for_one策略):
supervisor:start_child(SupRef, ChildSpec) -> startchild_ret()
。
您可以使用函数
访问该过程计数 supervisor:count_children(SupRef) -> PropListOfCounts
。
结果是形式的预言
[{specs,N1},{active,N2},{supervisors,N3},{workers,N4}]
(不能保证订单!)
如果您想要有关活动过程的更多信息,也可以使用
supervisor:which_children(SupRef) -> [{Id, Child, Type, Modules}]
,但是当主管管理"大量"儿童时,不建议这样做。
实现限制时,您基本上是"自己"。有某些工具可以帮助您,但是我认为"我如何避免产生太多流程?"一个总体问题。仍然保持。诀窍是跟踪过程数量的位置。
一种erlang-idiomatic的方法是拥有一个包含计数器的过程。每当您想产生新的过程时,您都会通过注册对代币的需求来询问是否允许您这样做。然后,您等待计数过程回复您。
那么计数过程是一个不错的模块化的人,为您维护限制。