[英]Erlang process event error
我基本上按照本網站上的教程了解一些Erlang:設計一個並發應用程序 ,我嘗試使用以下命令運行下面的代碼並在第48行遇到錯誤。我確實關閉了我的防火牆以防萬一問題但沒有運氣。 我在windows xp SP3上。
9> c(事件)。
【確定,事件}
10> f()。
好
11>事件:開始(“事件”,0)。
= ERROR REPORT ==== 2013年2月9日:: 15:05:07 ===進程錯誤<0.61.0>退出值:{function_clause,[{event,time_to_go,[0],[{file “event.erl”},{線,48}]},{事件時,init,3,[{文件, “event.erl”},{線,31}]}]}
<0.61.0>
12>
-module(event).
-export([start/2, start_link/2, cancel/1]).
-export([init/3, loop/1]).
-record(state, {server,
name="",
to_go=0}).
%%% Public interface
start(EventName, DateTime) ->
spawn(?MODULE, init, [self(), EventName, DateTime]).
start_link(EventName, DateTime) ->
spawn_link(?MODULE, init, [self(), EventName, DateTime]).
cancel(Pid) ->
%% Monitor in case the process is already dead
Ref = erlang:monitor(process, Pid),
Pid ! {self(), Ref, cancel},
receive
{Ref, ok} ->
erlang:demonitor(Ref, [flush]),
ok;
{'DOWN', Ref, process, Pid, _Reason} ->
ok
end.
%%% Event's innards
init(Server, EventName, DateTime) ->
loop(#state{server=Server,
name=EventName,
to_go=time_to_go(DateTime)}).
%% Loop uses a list for times in order to go around the ~49 days limit
%% on timeouts.
loop(S = #state{server=Server, to_go=[T|Next]}) ->
receive
{Server, Ref, cancel} ->
Server ! {Ref, ok}
after T*1000 ->
if Next =:= [] ->
Server ! {done, S#state.name};
Next =/= [] ->
loop(S#state{to_go=Next})
end
end.
%%% private functions
time_to_go(TimeOut={{_,_,_}, {_,_,_}}) ->
Now = calendar:local_time(),
ToGo = calendar:datetime_to_gregorian_seconds(TimeOut) -
calendar:datetime_to_gregorian_seconds(Now),
Secs = if ToGo > 0 -> ToGo;
ToGo =< 0 -> 0
end,
normalize(Secs).
%% Because Erlang is limited to about 49 days (49*24*60*60*1000) in
%% milliseconds, the following function is used
normalize(N) ->
Limit = 49*24*60*60,
[N rem Limit | lists:duplicate(N div Limit, Limit)].
它在您的機器上純粹在本地運行,因此防火牆不會影響它。
問題是你在啟動event:start("Event",0).
時給出的第二個參數event:start("Event",0).
錯誤原因:
{function_clause,[{event,time_to_go,[0],[{file,"event.erl"},{line,48}]},{event,init,3,[{file,"event.erl"},{line,31}]}]}
說它是一個function_clause
錯誤,這意味着函數定義中沒有與參數匹配的子句。 它還告訴你它是函數event:time_to_go/1
第48行的event:time_to_go/1
失敗並且使用參數0
調用它。
你看一下函數time_to_go/
你會看到它期望它的參數是2個元素的元組,其中每個元素是3個元素的元組:
time_to_go(TimeOut={{_,_,_}, {_,_,_}}) ->
該參數的結構是{{Year,Month,Day},{Hour,Minute,Second}}
。 如果您向后跟隨此參數, time_to_go/
init/3
調用time_to_go/1
,其中time_to_go/1
, DateTime
的參數是init/3
的第3個參數。 現在差不多了。 現在init/3
是進程在start/2
(和start_link / 2 ) and the 3rd argument to
中生成的函數, ) and the 3rd argument to
init / 3 is the second argument to
start / 2` is the second argument to
。
所以當你調用event:start("Event",0).
它是0
,它被傳遞到新的peocess中的調用time_to_go/1
函數。 格式錯了。 你應該用event:start("Event", {{2013,3,24},{17,53,62}}).
類的東西來調用它event:start("Event", {{2013,3,24},{17,53,62}}).
要為rvirding的答案添加背景,您會收到錯誤,因為就我所知,該示例將一直運行到最終的代碼段。 首先使用normalize
函數,它處理問題。 然后在上面問題的例子后面的段落,文字說:
它的工作原理! 對事件模塊感到厭煩的最后一件事是我們必須輸入剩余的時間(以秒為單位)。 如果我們可以使用標准格式,例如Erlang的日期時間(
{{Year, Month, Day}, {Hour, Minute, Second}}
)會好得多。 只需添加以下函數即可計算計算機當前時間與插入延遲之間的差異:
下一個代碼片段引入了僅占用日期/時間的代碼位,並將其更改為最后剩余時間。
我無法輕松鏈接到文件的所有過渡版本,這就是為什么在這種情況下直接使用示例嘗試鏈接文件不能輕松工作的原因。 如果代碼是循序漸進的,片段摘錄,一切都應該正常。 對困惑感到抱歉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.