我正在尝试使用动态创建的原子名称注册几个进程,如下所示:
keep_alive(Name, Fun) ->
register(Name, Pid = spawn(Fun)),
on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end).
monitor_some_processes(N) ->
%% create N processes that restart automatically when killed
for(1, N, fun(I) ->
Mesg = io_lib:format("I'm process ~p~n", [I]),
Name = list_to_atom(io_lib:format("zombie~p", [I])),
keep_alive(Name, fun() -> zombie(Mesg) end)
end).
for(N, N, Fun) -> [Fun(N)];
for(I, N, Fun) -> [Fun(I)|for(I+1, N, Fun)].
zombie(Mesg) ->
io:format(Mesg),
timer:sleep(3000),
zombie(Mesg).
Run Code Online (Sandbox Code Playgroud)
该list_to_atom/1电话会导致错误:
43> list_to_atom(io_lib:format("zombie~p", [1])).
** exception error: bad argument
in function list_to_atom/1
called as list_to_atom([122,111,109,98,105,101,"1"])
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?还有,有更好的方法吗?
TL; DR
你不应该动态生成原子.从您的代码片段中可以看出,您可能正在尝试找到灵活命名过程的方法,但原子不是它.使用某种类型的K/V商店而不是register/2.
讨论
原子限制是有原因的.它们应该代表程序的永恒结构,而不是它的当前状态.原子等限制性,我想你是什么真的希望能够做的是注册使用任意二郎价值,而不仅仅是原子的过程,更自由地引用它们.
如果是这种情况,请选择以下四种方法之一:
#{Name => Pid}.