消息传递时 Erlang 处理 "badarg" 错误
Erlang handling "badarg" error when message passing
我是 Erlang 的新手,我试图通过消息传递将从一个函数获得的结果传递给另一个函数,但我不确定为什么当我执行 ie main 时它会给我 badarg 错误! {数字,1,100}。我已尝试进行一些更改,如灰色部分所示,但使用 From 时消息未通过。这是我的代码:
-module(numbers).
-export([start_main/0,main/2,proc/0,sumNumbers/2]).
main(Total, N) ->
if
N == 0 ->
io:format("Total: ~p ~n", [Total]);
true ->
true
end,
receive
{numbers, Low, High} ->
Half = round(High/2),
Pid1 = spawn(numbers, proc, []),
Pid2 = spawn(numbers, proc, []),
Pid1 ! {work, Low, Half},
Pid2 ! {work, Half+1, High};
%% Pid1 ! {work, self(), Low, Half},
%% Pid2 ! {work, self(), Half+1, High},
{return, Result} ->
io:format("Received ~p ~n", [Result]),
main(Total+Result, N-1)
end.
proc() ->
receive
{work, Low, High} ->
io:format("Processing ~p to ~p ~n", [Low, High]),
Res = sumNumbers(Low,High),
main ! {return, Res},
proc()
%% {work, From, Low, High} ->
%% io:format("Processing ~p to ~p ~n", [Low, High]),
%% Res = sumNumbers(Low,High),
%% From ! {return, Res},
%% proc()
end.
sumNumbers(Low, High) ->
Lst = lists:seq(Low,High),
lists:sum(Lst).
start_main() ->
register(main, spawn(numbers, main, [0,2])).
如果你从main ! Message
得到一个badarg
,这意味着没有进程注册在名称main
下。它要么没有开始,要么一开始就没有正确注册,或者在某个时候已经死了。您可以添加更多打印语句来跟踪发生的情况。
您可以使用erlang:registered/2
查看注册的内容。
执行此功能:
start_main() ->
register(main, spawn(numbers, main, [0,2])).
将启动一个名为 main
的进程,该进程执行函数 numbers:main/2
。函数numbers:main/2
开始执行后,进入接收子句等待消息。
如果您随后执行函数proc/0
,它也会进入接收子句并等待消息。如果你向进程 运行 proc/0
发送一条消息,例如 {work, 1, 3}
,那么 proc/0
将向 numbers:main/2
发送一条消息,例如 {return, 6}
; numbers:main/2
将显示一些输出。证明如下:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(numbers).
{ok,numbers}
2> numbers:start_main().
true
3> Pid = spawn(numbers, proc, []).
<0.73.0>
4> Pid ! {work, 1, 3}.
Processing 1 to 3
{work,1,3}
Received 6
5>
如您所见,没有 badarg
错误。当你声称发生了什么事时,你需要用证据来支持它——仅仅说发生了什么事是不够的。
当您向 main 发送第一条消息时,它由带有消息 {numbers,1,100}
的接收语句处理,在此语句中,您生成了两次 proc() 函数,并终止了接收语句。
因此,主进程终止,不再注册,一旦 proc 函数尝试在第 main ! {return, Res},
行发送消息,您就会收到 badarg 错误。
您需要像在第 main(Total+Result, N-1)
行那样递归调用主函数,以使主进程保持活动状态。 (参见 RichardC 的回答)
我是 Erlang 的新手,我试图通过消息传递将从一个函数获得的结果传递给另一个函数,但我不确定为什么当我执行 ie main 时它会给我 badarg 错误! {数字,1,100}。我已尝试进行一些更改,如灰色部分所示,但使用 From 时消息未通过。这是我的代码:
-module(numbers).
-export([start_main/0,main/2,proc/0,sumNumbers/2]).
main(Total, N) ->
if
N == 0 ->
io:format("Total: ~p ~n", [Total]);
true ->
true
end,
receive
{numbers, Low, High} ->
Half = round(High/2),
Pid1 = spawn(numbers, proc, []),
Pid2 = spawn(numbers, proc, []),
Pid1 ! {work, Low, Half},
Pid2 ! {work, Half+1, High};
%% Pid1 ! {work, self(), Low, Half},
%% Pid2 ! {work, self(), Half+1, High},
{return, Result} ->
io:format("Received ~p ~n", [Result]),
main(Total+Result, N-1)
end.
proc() ->
receive
{work, Low, High} ->
io:format("Processing ~p to ~p ~n", [Low, High]),
Res = sumNumbers(Low,High),
main ! {return, Res},
proc()
%% {work, From, Low, High} ->
%% io:format("Processing ~p to ~p ~n", [Low, High]),
%% Res = sumNumbers(Low,High),
%% From ! {return, Res},
%% proc()
end.
sumNumbers(Low, High) ->
Lst = lists:seq(Low,High),
lists:sum(Lst).
start_main() ->
register(main, spawn(numbers, main, [0,2])).
如果你从main ! Message
得到一个badarg
,这意味着没有进程注册在名称main
下。它要么没有开始,要么一开始就没有正确注册,或者在某个时候已经死了。您可以添加更多打印语句来跟踪发生的情况。
您可以使用erlang:registered/2
查看注册的内容。
执行此功能:
start_main() ->
register(main, spawn(numbers, main, [0,2])).
将启动一个名为 main
的进程,该进程执行函数 numbers:main/2
。函数numbers:main/2
开始执行后,进入接收子句等待消息。
如果您随后执行函数proc/0
,它也会进入接收子句并等待消息。如果你向进程 运行 proc/0
发送一条消息,例如 {work, 1, 3}
,那么 proc/0
将向 numbers:main/2
发送一条消息,例如 {return, 6}
; numbers:main/2
将显示一些输出。证明如下:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> c(numbers).
{ok,numbers}
2> numbers:start_main().
true
3> Pid = spawn(numbers, proc, []).
<0.73.0>
4> Pid ! {work, 1, 3}.
Processing 1 to 3
{work,1,3}
Received 6
5>
如您所见,没有 badarg
错误。当你声称发生了什么事时,你需要用证据来支持它——仅仅说发生了什么事是不够的。
当您向 main 发送第一条消息时,它由带有消息 {numbers,1,100}
的接收语句处理,在此语句中,您生成了两次 proc() 函数,并终止了接收语句。
因此,主进程终止,不再注册,一旦 proc 函数尝试在第 main ! {return, Res},
行发送消息,您就会收到 badarg 错误。
您需要像在第 main(Total+Result, N-1)
行那样递归调用主函数,以使主进程保持活动状态。 (参见 RichardC 的回答)