Erlang产生问题 [英] Erlang spawn problems

查看:154
本文介绍了Erlang产生问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在erlang中遇到'spawn'问题,似乎程序在一段时间后就死了。以下是简单的代码:

  -module(simple)。 
-export([server / 1,client / 1,owner / 1,spawn_n / 2,start / 1,main / 1])。

服务器(状态) - >
收到
{request,Return_PID} - >
io:format(SERVER〜w:从〜w〜n收到的客户端请求,[self(),Return_PID]),
NewState = State + 1,
Return_PID! {hit_count,NewState},
server(NewState);

{server_owner,Owner_PID} - >
io:format(SERVER〜w:所有者请求收到〜w〜n,[self(),Owner_PID]),
Owner_PID! {hit_count,State},
server(State);
重置 - >
io:format(SERVER〜w:State reset to zero。〜n,[self()]),
server(0)

end。



客户端(Server_Address) - >
Server_Address! {request,self()},
收到
{hit_count,Number} - >
io:format(CLIENT〜w:命中计数为〜w〜n,[self(),Number])
end。



所有者(Server_PID) - >
定时器:睡眠(随机:统一(100)),
Server_PID! {server_owner,self()},
接收
{hit_count,Number}当Number> 5 - >
io:format(OWNER:Hit count is〜w,reseting counter。〜n,[Number]),
Server_PID!重置,
所有者(Server_PID);
{hit_count,Number}当Number < 5 - >
io:format(OWNER〜w:Hit count was〜w〜n,[self(),Number]),
owner(Server_PID)
end。




spawn_n(N,Server_PID) - >
如果
N> 0 - >
spawn(simple,client,[Server_PID]),
timer:sleep(random:uniform(100)),
spawn_n(N-1,Server_PID);
N == 0 - >
io:format(最后客户端生成。〜n)
结束。



start(N) - >
Server_PID = spawn(simple,server,[0]),
spawn(simple,owner,[Server_PID]),
spawn(simple,spawn_n,[N,Server_PID])。


main([Arg]) - >
N = list_to_integer(atom_to_list(Arg)),
start(N),
init:stop()。

运行它时,我得到一个例子:

  erl -noshell -s simple main 20 

SERVER< 0.28.0> ;:从< 0.31.0>收到的客户端请求
CLIENT< 0.31.0> ;:命中计数为1
SERVER< 0.28.0>:从< 0.29.0>收到的所有者请求
SERVER< 0.28.0> ;:从< 0.32.0>收到的客户端请求
OWNER< 0.29.0> ;:命中计数为1
CLIENT< 0.32.0> ;:命中次数为2
SERVER< 0.28.0> ;:从0.29.0>
SERVER< 0.28.0> ;:从< 0.33.0>收到的客户端请求
OWNER< 0.29.0> ;:命中次数为2
CLIENT< 0.33.0> ;:命中次数为3
SERVER< 0.28.0> ;:从0.29.0>
SERVER< 0.28.0> ;:从< 0.34.0>收到的客户端请求
OWNER< 0.29.0> ;:命中计数为3
CLIENT< 0.34.0> ;:命中次数为4
SERVER< 0.28.0> ;:从0.29.0>
SERVER< 0.28.0> ;:从< 0.35.0>收到的客户端请求
OWNER< 0.29.0> ;:命中计数为4
CLIENT< 0.35.0> ;:命中计数为5
SERVER< 0.28.0> ;:从0.29.0>
SERVER< 0.28.0> ;:从< 0.36.0>收到的客户端请求
CLIENT< 0.36.0> ;:命中计数为6
SERVER< 0.28.0> ;:从< 0.37.0>收到的客户端请求
CLIENT< 0.37.0> ;:命中次数为7
SERVER< 0.28.0> ;:从< 0.38.0>收到的客户端请求
CLIENT< 0.38.0> ;:命中次数为8
SERVER< 0.28.0> ;:从< 0.39.0>收到的客户端请求
CLIENT< 0.39.0> ;:命中次数为9
SERVER< 0.28.0> ;:从< 0.40.0>收到的客户端请求
CLIENT< 0.40.0> ;:命中次数为10
SERVER< 0.28.0> ;:从< 0.41.0>收到的客户端请求
CLIENT< 0.41.0> ;:命中计数为11
SERVER< 0.28.0> ;:从< 0.42.0>收到的客户端请求
CLIENT< 0.42.0> ;:命中计数为12
SERVER< 0.28.0> ;:从< 0.43.0>收到的客户端请求
CLIENT< 0.43.0> ;:命中次数为13
SERVER< 0.28.0> ;:从< 0.44.0>收到的客户端请求
CLIENT< 0.44.0> ;:命中次数为14
SERVER< 0.28.0> ;:从< 0.45.0>
CLIENT< 0.45.0> ;:命中计数为15
SERVER< 0.28.0> ;:从< 0.46.0>收到的客户端请求
CLIENT< 0.46.0> ;:命中次数为16
SERVER< 0.28.0> ;:从< 0.47.0>收到的客户端请求
CLIENT< 0.47.0> ;:命中次数为17
SERVER< 0.28.0> ;:从< 0.48.0>收到的客户端请求
CLIENT< 0.48.0> ;:命中数为18
{error_logger,{{2011,6,27},{12,57,8}},〜s〜n,[过程< 0.28.0> with ex
it value:{terminated,[{io,format,[< 0.22.0>,\SERVER〜w:客户端请求收到
从〜w〜n\,[<0.28.0>,<0.49.0]]},{simple,server,1}]} \\\
]}

我没有得到它。这些过程死了还是什么?它不应该终止!
我正在Windows 7上运行,如果它可能是Windows相关的东西。



谢谢



编辑:记住应用程序会发生什么:start(sasl)。之前:

  C:\Program Files\erl5.8.4\bin> erl 
Eshell V5.8.4 (中止与^ G)
1>应用程序:启动(SASL)。
ok

=进度报告==== 2011年6月27日:: 16:03:55 ===
主管:{local,sasl_safe_sup}
开始:[{pid,< 0.37.0>},
{name,alarm_handler},
{mfargs,{alarm_handler,start_link,[]}},
{restart_type,permanent} ,
{shutdown,2000},
{child_type,worker}]
2>
=进度报告==== 2011年6月27日:: 16:03:55 ===
主管:{local,sasl_safe_sup}
开始:[{pid,<0.38 .0>},
{name,overload},
{mfargs,{overload,start_link,[]}},
{restart_type,permanent},
{shutdown,2000 },
{child_type,worker}]
2>
=进度报告==== 2011年6月27日:: 16:03:55 ===
主管:{local,sasl_sup}
开始:[{pid,<0.36 .0>},
{name,sasl_safe_sup},
{mfargs,
{supervisor,start_link,
[{local,sasl_safe_sup},sasl,safe
{ restart_type,permanent},
{shutdown,infinity},
{child_type,supervisor}]
2>
=进度报告==== 2011年6月27日:: 16:03:55 ===
主管:{local,sasl_sup}
开始:[{pid,<0.39 。
{name,release_handler},
{mfargs,{release_handler,start_link,[]}}
{restart_type,permanent},
{shutdown,2000} ,
{child_type,worker}]
2>
=进度报告==== 2011年6月27日:: 16:03:55 ===
应用程序:sasl
started_at:nonode @ nohost
2>简单:主([ 20’ ])。
ok
SERVER< 0.42.0> ;:从< 0.45.0>收到的客户端请求
3>客户< 0.45.0>:命中数为1
3> SERVER< 0.42.0>:从< 0.43.0>收到的所有者请求
3> SERVER< 0.42.0>:从< 0.47.0>收到的客户端请求
3> OWNER< 0.43.0> ;:命中计数为1
3>客户< 0.47.0> ;:命中次数为2
3> SERVER< 0.42.0>:从< 0.43.0>收到的所有者请求
3> SERVER< 0.42.0>:从< 0.48.0>收到的客户端请求
3> OWNER <0.43.0:命中次数为2
3>客户< 0.48.0> ;:命中数为3
3> SERVER< 0.42.0>:从< 0.43.0>收到的所有者请求
3> SERVER< 0.42.0>:从< 0.49.0>收到的客户端请求
3> OWNER< 0.43.0>:命中数为3
3>客户< 0.49.0> ;:命中数为4
3> SERVER< 0.42.0>:从< 0.43.0>收到的所有者请求
3> SERVER< 0.42.0>:从< 0.50.0>收到的客户端请求
3> OWNER <0.43.0:命中数为4
3>客户< 0.50.0>:命中数为5
3> SERVER< 0.42.0>:从< 0.43.0>收到的所有者请求
3> SERVER< 0.42.0>:从< 0.51.0>收到的客户端请求
3>客户< 0.51.0> ;:命中数为6
3> SERVER< 0.42.0>:从< 0.52.0>收到的客户端请求
3>客户< 0.52.0> ;:命中数为7
3> SERVER< 0.42.0>:从< 0.53.0>收到的客户端请求
3>客户< 0.53.0> ;:命中数为8
3> SERVER< 0.42.0>:从< 0.54.0>收到的客户端请求
3>客户< 0.54.0> ;:命中数为9
3> SERVER< 0.42.0> ;:从< 0.55.0>收到的客户端请求
3>客户< 0.55.0> ;:命中数为10
3> SERVER< 0.42.0> ;:从< 0.56.0>收到的客户端请求
3>客户< 0.56.0> ;:命中数为11
3> SERVER< 0.42.0> ;:从< 0.57.0>收到的客户端请求
3>客户< 0.57.0> ;:命中数为12
3> SERVER< 0.42.0>:从< 0.58.0>收到的客户端请求
3>客户< 0.58.0> ;:命中计数是13
3> SERVER< 0.42.0> ;:从< 0.59.0>收到的客户端请求
3>客户< 0.59.0> ;:命中数为14
3> SERVER< 0.42.0>:从< 0.60.0>收到的客户端请求
3>客户< 0.60.0>:命中数为15
3> SERVER< 0.42.0>:从< 0.61.0>收到的客户端请求
3>客户< 0.61.0> ;:命中数为16
3> SERVER< 0.42.0>:从< 0.62.0>收到的客户端请求
3>客户< 0.62.0> ;:命中数为17
3> SERVER< 0.42.0>:从< 0.63.0>收到的客户端请求
3>客户< 0.63.0> ;:命中数为18
3> {error_logger,{{2011,6,27},{16,3,58}},〜s〜n,[错误在proc
退出值:{terminated,[{io,format, < 0.23.0>从〜w〜n\,[< 0.42.0>,< 0.64.0>]中的SERVER〜w:Cli
服务器,1}]} \\\
]}


解决方案

>您在生成之后立即调用 init:stop()。你如何确保所有的流程正确完成?您可能需要在 main 中阻止接收,并在其他人完成后通知主进程。


I am having problem with 'spawn' in erlang, it seems processes just die after awhile. Here's the simple code:

-module(simple).
-export([server/1, client/1, owner/1, spawn_n/2, start/1, main/1]).

server(State) ->
receive
    {request,Return_PID} ->
        io:format("SERVER ~w: Client request recieved from ~w~n", [self(),Return_PID]),
        NewState = State + 1,
        Return_PID ! {hit_count,NewState},
        server(NewState);

    {server_owner,Owner_PID} ->
        io:format("SERVER ~w: Owner request recieved from ~w~n", [self(), Owner_PID]),
        Owner_PID ! {hit_count,State},
        server(State);
    reset ->
        io:format("SERVER ~w: State reset to zero.~n", [self()]),
        server(0)

end.



client(Server_Address) ->
Server_Address ! {request, self()},
receive
    {hit_count,Number} ->
        io:format("CLIENT ~w: Hit count was ~w~n", [self(),Number])
end.



owner(Server_PID) ->
timer:sleep(random:uniform(100)),
Server_PID ! {server_owner,self()},
receive 
    {hit_count,Number} when Number > 5 ->
        io:format("OWNER: Hit count is ~w , reseting counter. ~n", [Number]),
        Server_PID ! reset,
        owner(Server_PID);
    {hit_count,Number} when Number < 5 ->
        io:format("OWNER ~w: Hit count was ~w~n", [self(), Number]),
        owner(Server_PID)
end.




spawn_n(N, Server_PID) ->
if
    N>0 ->
        spawn(simple,client,[Server_PID]),
        timer:sleep(random:uniform(100)),
        spawn_n(N-1,Server_PID);
    N==0 ->
        io:format("Last client spawned. ~n")
end.



start(N) ->
Server_PID = spawn(simple,server,[0]),
spawn(simple,owner,[Server_PID]),
spawn(simple,spawn_n,[N,Server_PID]).


main([Arg]) ->
N = list_to_integer(atom_to_list(Arg)),
start(N),
init:stop().

Here's an example I get when running it:

erl -noshell -s simple main 20

SERVER <0.28.0>: Client request recieved from <0.31.0>
CLIENT <0.31.0>: Hit count was 1
SERVER <0.28.0>: Owner request recieved from <0.29.0>
SERVER <0.28.0>: Client request recieved from <0.32.0>
OWNER <0.29.0>: Hit count was 1
CLIENT <0.32.0>: Hit count was 2
SERVER <0.28.0>: Owner request recieved from <0.29.0>
SERVER <0.28.0>: Client request recieved from <0.33.0>
OWNER <0.29.0>: Hit count was 2
CLIENT <0.33.0>: Hit count was 3
SERVER <0.28.0>: Owner request recieved from <0.29.0>
SERVER <0.28.0>: Client request recieved from <0.34.0>
OWNER <0.29.0>: Hit count was 3
CLIENT <0.34.0>: Hit count was 4
SERVER <0.28.0>: Owner request recieved from <0.29.0>
SERVER <0.28.0>: Client request recieved from <0.35.0>
OWNER <0.29.0>: Hit count was 4
CLIENT <0.35.0>: Hit count was 5
SERVER <0.28.0>: Owner request recieved from <0.29.0>
SERVER <0.28.0>: Client request recieved from <0.36.0>
CLIENT <0.36.0>: Hit count was 6
SERVER <0.28.0>: Client request recieved from <0.37.0>
CLIENT <0.37.0>: Hit count was 7
SERVER <0.28.0>: Client request recieved from <0.38.0>
CLIENT <0.38.0>: Hit count was 8
SERVER <0.28.0>: Client request recieved from <0.39.0>
CLIENT <0.39.0>: Hit count was 9
SERVER <0.28.0>: Client request recieved from <0.40.0>
CLIENT <0.40.0>: Hit count was 10
SERVER <0.28.0>: Client request recieved from <0.41.0>
CLIENT <0.41.0>: Hit count was 11
SERVER <0.28.0>: Client request recieved from <0.42.0>
CLIENT <0.42.0>: Hit count was 12
SERVER <0.28.0>: Client request recieved from <0.43.0>
CLIENT <0.43.0>: Hit count was 13
SERVER <0.28.0>: Client request recieved from <0.44.0>
CLIENT <0.44.0>: Hit count was 14
SERVER <0.28.0>: Client request recieved from <0.45.0>
CLIENT <0.45.0>: Hit count was 15
SERVER <0.28.0>: Client request recieved from <0.46.0>
CLIENT <0.46.0>: Hit count was 16
SERVER <0.28.0>: Client request recieved from <0.47.0>
CLIENT <0.47.0>: Hit count was 17
SERVER <0.28.0>: Client request recieved from <0.48.0>
CLIENT <0.48.0>: Hit count was 18
{error_logger,{{2011,6,27},{12,57,8}},"~s~n",["Error in process <0.28.0> with ex
it value: {terminated,[{io,format,[<0.22.0>,\"SERVER ~w: Client request recieved
 from ~w~n\",[<0.28.0>,<0.49.0>]]},{simple,server,1}]}\n"]}

I don't get it. The processes just die or something? It shouldnt terminate! I am running on windows 7 if it might be something windows-related.

Thanks

EDIT: heres what happens by doing application:start(sasl). before:

C:\Program Files\erl5.8.4\bin>erl
Eshell V5.8.4  (abort with ^G)
1> application:start(sasl).
ok

=PROGRESS REPORT==== 27-Jun-2011::16:03:55 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,<0.37.0>},
                       {name,alarm_handler},
                       {mfargs,{alarm_handler,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]
2>
=PROGRESS REPORT==== 27-Jun-2011::16:03:55 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,<0.38.0>},
                       {name,overload},
                       {mfargs,{overload,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]
2>
=PROGRESS REPORT==== 27-Jun-2011::16:03:55 ===
          supervisor: {local,sasl_sup}
             started: [{pid,<0.36.0>},
                       {name,sasl_safe_sup},
                       {mfargs,
                           {supervisor,start_link,
                               [{local,sasl_safe_sup},sasl,safe
                       {restart_type,permanent},
                       {shutdown,infinity},
                       {child_type,supervisor}]
2>
=PROGRESS REPORT==== 27-Jun-2011::16:03:55 ===
          supervisor: {local,sasl_sup}
             started: [{pid,<0.39.0>},
                       {name,release_handler},
                       {mfargs,{release_handler,start_link,[]}}
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]
2>
=PROGRESS REPORT==== 27-Jun-2011::16:03:55 ===
         application: sasl
          started_at: nonode@nohost
2> simple:main(['20']).
ok
SERVER <0.42.0>: Client request recieved from <0.45.0>
3> CLIENT <0.45.0>: Hit count was 1
3> SERVER <0.42.0>: Owner request recieved from <0.43.0>
3> SERVER <0.42.0>: Client request recieved from <0.47.0>
3> OWNER <0.43.0>: Hit count was 1
3> CLIENT <0.47.0>: Hit count was 2
3> SERVER <0.42.0>: Owner request recieved from <0.43.0>
3> SERVER <0.42.0>: Client request recieved from <0.48.0>
3> OWNER <0.43.0>: Hit count was 2
3> CLIENT <0.48.0>: Hit count was 3
3> SERVER <0.42.0>: Owner request recieved from <0.43.0>
3> SERVER <0.42.0>: Client request recieved from <0.49.0>
3> OWNER <0.43.0>: Hit count was 3
3> CLIENT <0.49.0>: Hit count was 4
3> SERVER <0.42.0>: Owner request recieved from <0.43.0>
3> SERVER <0.42.0>: Client request recieved from <0.50.0>
3> OWNER <0.43.0>: Hit count was 4
3> CLIENT <0.50.0>: Hit count was 5
3> SERVER <0.42.0>: Owner request recieved from <0.43.0>
3> SERVER <0.42.0>: Client request recieved from <0.51.0>
3> CLIENT <0.51.0>: Hit count was 6
3> SERVER <0.42.0>: Client request recieved from <0.52.0>
3> CLIENT <0.52.0>: Hit count was 7
3> SERVER <0.42.0>: Client request recieved from <0.53.0>
3> CLIENT <0.53.0>: Hit count was 8
3> SERVER <0.42.0>: Client request recieved from <0.54.0>
3> CLIENT <0.54.0>: Hit count was 9
3> SERVER <0.42.0>: Client request recieved from <0.55.0>
3> CLIENT <0.55.0>: Hit count was 10
3> SERVER <0.42.0>: Client request recieved from <0.56.0>
3> CLIENT <0.56.0>: Hit count was 11
3> SERVER <0.42.0>: Client request recieved from <0.57.0>
3> CLIENT <0.57.0>: Hit count was 12
3> SERVER <0.42.0>: Client request recieved from <0.58.0>
3> CLIENT <0.58.0>: Hit count was 13
3> SERVER <0.42.0>: Client request recieved from <0.59.0>
3> CLIENT <0.59.0>: Hit count was 14
3> SERVER <0.42.0>: Client request recieved from <0.60.0>
3> CLIENT <0.60.0>: Hit count was 15
3> SERVER <0.42.0>: Client request recieved from <0.61.0>
3> CLIENT <0.61.0>: Hit count was 16
3> SERVER <0.42.0>: Client request recieved from <0.62.0>
3> CLIENT <0.62.0>: Hit count was 17
3> SERVER <0.42.0>: Client request recieved from <0.63.0>
3> CLIENT <0.63.0>: Hit count was 18
3> {error_logger,{{2011,6,27},{16,3,58}},"~s~n",["Error in proc
 exit value: {terminated,[{io,format,[<0.23.0>,\"SERVER ~w: Cli
ved from ~w~n\",[<0.42.0>,<0.64.0>]]},{simple,server,1}]}\n"]}

解决方案

You are calling init:stop() immediately after your spawns. How are you going to make sure all your processes are properly finished? You probably need to block on receive in main and notify main process when others are done.

这篇关于Erlang产生问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆