在管理员功能中捕获badarg错误

时间:2015-10-10 14:56:05

标签: parallel-processing erlang

这里我有一个程序可以做一些简单的数学运算。该计划与主管一起运行。

然而,有时程序会在我运行时崩溃。特别是当我第一次运行calc_sup_start_link(),然后运行calc_test()时。任何人有任何想法?该计划如下:

calc_sup_start_link() ->
  spawn_link(fun calc_sup/0).


calc_sup() ->
  process_flag(trap_exit, true),
  {ok, _Pid} = calc_start_link(),
  receive
    {'EXIT', _From, normal} ->
      ok;
    {'EXIT', _From, _Reason} ->
    calc_sup() % Crash: restart
  end.


calc_start_link() ->
  S = spawn_link(fun calc_loop/0),
  register(calc, S),
  {ok, S}


calc_loop() ->
  receive
    {add, P, A, B} ->
      P ! {add_reply, A + B},
      calc_loop();
    {mul, P, A, B} ->
      {_, _, N} = now(),
      if N rem 5 =/= 0 -> ok end,
      P ! {mul_reply, A * B},
      calc_loop()
  end.


calc_add(A, B) ->
  calc ! {add, self(), A, B},
  receive
    {add_reply, C} -> C
  end.


calc_mul(A, B) ->
  calc ! {mul, self(), A, B},
  receive
    {mul_reply, C} -> C
  end.


calc_client(X, Y, Z) ->
  Q = calc_mul(X, Y),
  timer:sleep(500),
  R = calc_add(Q, 3),
  timer:sleep(500),
  calc_mul(R, Z).


calc_test() ->
  io:format("Running calc_client(2, 4, 5)~n"),
  R = calc_client(2, 4, 5),
  io:format("calc_client(2, 4, 5) returned ~p~n", [R]).

2 个答案:

答案 0 :(得分:1)

我认为它在这个集团中崩溃了:

theano.scan

实际上如果N是5的倍数,(N rem 5)== 0并且没有分支来评估if的结果,并且在erlang中所有语句都必须返回一个值。你可以在shell中验证:

calc_loop() ->
  receive
    {add, P, A, B} ->
      P ! {add_reply, A + B},
      calc_loop();
    {mul, P, A, B} ->
      {_, _, N} = now(),
      if N rem 5 =/= 0 -> ok end, %% if doesn't work as in C or java !!!
      P ! {mul_reply, A * B},
      calc_loop()
  end.

在你的情况下你应该写:

1> if ((11 rem 5) =/= 0) -> ok end.
ok
2> if ((10 rem 5) =/= 0) -> ok end.
** exception error: no true branch found when evaluating an if expression
3> if ((10 rem 5) =/= 0) -> ok; true -> false end.
false
4> 

如果N是5的倍数,这将执行乘法和循环;并且在其他情况下它将以正常的原因终止(我不确定这是你想要做的,因为if表达式没有完成)

答案 1 :(得分:0)

如果你自己编写尾递归, 更好的方法是始终调用外部函数(代码只在内存中保存两个版本)。

像这样: 将calc_loop()更改为?MODULE:calc_loop()。

它将始终调用最新版本的代码。

http://www.erlang.org/doc/reference_manual/code_loading.html#id88331