首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拖延是行不通的

拖延是行不通的
EN

Stack Overflow用户
提问于 2013-11-07 12:53:13
回答 2查看 85关注 0票数 0

我正在制作一个活动日历,作为学校的一项任务,我对此并不陌生。问题是,当我对循环中的接收部分执行延迟时,我的表就会消失。我在互联网上和我的代码中查找错误2天。

事件是一个元组=> {Time (tuple类似于now()、make_ref()}、NotifyPid、Load} ) getTime通常会返回一个整数

代码语言:javascript
复制
-module(calender).
-export([start/0, start_new/0, post/1, postincr/1, gettime/0]).
-export ([kalender/0, getTime/1, increment/1, makeTime/1]). % internal use only

%% @doc Starts the program
start() ->
    case whereis('event manager') =:= undefined of
        true ->
            register('event manager', spawn(calender, kalender, [])),
            {ok, 'event manager'};
        false ->
            {event_not_made}
    end.

%% @doc Starts a new program even program already exist but kills it first
start_new() ->
    case whereis('event manager') =:= undefined orelse unregister('event manager') of
        true ->
            ets:delete(calend),
            register('event manager', spawn(calender, kalender, [])),
            {ok, 'event manager'};
        false ->
            {ok, event_not_made}
    end.

% Puts Events into sorted table
% Time is an integer value in milliseconds  
post(Event) ->
    'event manager'!{post, Event},
    {ok, gettime()}.

%% @doc Puts Events into sorted table
%% Increment is an integer value which will be added to the present time
%% The increment value of time is in milliseconds
%% @end
postincr(Event) ->
    'event manager'!{postincr, Event},
    {ok, gettime()}.

%% @doc Gives the difference in time between present and time at start
gettime() ->
    'event manager'!{gettime, self()},
    receive
        T -> T
    end.

%% @private Calculates the difference of time between the present time and Event time
getTime(Time) ->
    NowTime = now(),
    timer:now_diff(Time, NowTime)div 1000.

%% @private Adds the incremental time of postincr to the present time
increment(Incr) ->
    {X, Y, Z} = now(),
    X1 = X * 1000000000000,
    Y1 = Y * 1000000,
    Incr1 = X1 + Y1 + Z + (Incr * 1000),
    makeTime(Incr1).

%% @private Changes integer to tuple of 3 values
makeTime(Time) ->
    X = Time div 1000000000000,
    Y = (Time rem 1000000000000) div 1000000,
    Z = Time rem 1000000,
    {X, Y, Z}.

%% @private Makes the sorted table, starts the loop
kalender() ->
    Cal = {ets:new(calend, [ordered_set, named_table, {keypos, 1}, public]), now()},
    loop(Cal).

%% @private Loops through the table and checks for received messages
loop(Cal) ->
    io:format("Loop start ~n"),
    {Calen, TimeAtStart} = Cal,

    io:format("Before case ~n"),
    case ets:first(Calen)  of
        '$end_of_table' ->
            io:format("end of table ~n"),
            {end_of_table};
        {Time, Ref} ->
            io:format("Before calculation event ~n"),
            Ms = getTime(Time),
            io:format("After getTime ~n"),
            if 
                Ms =< 0 ->
                    io:format("Ms =< 0 ~n"),
                    [Event | _Rest] = ets:lookup(Calen, {Time, Ref}),
                    io:format("~p~n", [Event]),
                    {{_Time1, _Ref1}, NotifyPid, _Load} = Event,
                    io:format("~p~n", [NotifyPid]),
                    NotifyPid!Event,
                    io:format("After event send ~n"),
                    ets:delete(Calen, {Time, Ref}),
                    io:format("After Ms =< 0 ~n");
                Ms > 0 ->
                    io:format("Event not done ~n"),
                    {event_not_yet_done}
            end,
            io:format("After calculation event ~n")
    end,

我认为从这里开始就出了问题:

代码语言:javascript
复制
io:format("Before Delay ~n"),
        % Gets the delay time
        Delay = case ets:first(Calen) of
            '$end_of_table' ->
                io:format("Delay infinity ~n"),
                infinity;
            {DelayTime, _DelayRef} ->
                io:format("~p~n", [DelayTime]), => the DelayTime has for example a value of {9283,823031,155000}

                Dl = getTime(DelayTime),
                case Dl > 0 of
                    true ->
                        Dl,
                        io:format("~p~n", [Dl]); => this io:format gives me on the screen a calculated value example: 7899995274337

                    false ->
                        0,
                        io:format("0 ~n")
                end,
                io:format("Delay time~n")
        end,

        io:format("Before receive ~n"),
        receive
            {post, PostEvent} -> 
                io:format("In post ~n"),
                {PostTimeI, Np, Ld} = PostEvent,
                PostRef = make_ref(),
                PostTimeT = makeTime((PostTimeI * 1000)),
                io:format("After making the tuples ~n"),
                io:format("~p   ~p  ~p  ~p  ~p~n", [PostTimeI, PostRef, PostTimeT, Np, Ld]),
                ets:insert(Calen, {{PostTimeT, PostRef}, Np, Ld}),
                io:format("After insert post ~p~n", [whereis('event manager')]);
            {postincr, PostIncrEvent} ->
                {Incr, Np, Ld} = PostIncrEvent,
                PostIncrRef = make_ref(),
                PostIncrTime = increment(Incr),
                ets:insert(Calen, {{PostIncrTime, PostIncrRef}, Np, Ld});
            {gettime, From} ->
                From!getTime(TimeAtStart)
            after
                Delay ->
                    io:format("Delaying ~n"),
                    {ok}
        end,
        io:format("After receive ~n"),
        loop(Cal).
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-08 19:28:59

我发现了我的问题:我正在测试我的代码,但是我没有Pid来测试,所以我使用了whereis('event manager')。相反,我不得不使用self()

票数 1
EN

Stack Overflow用户

发布于 2013-11-07 17:57:57

问题可能是您的进程产生了start/0函数崩溃。当进程崩溃时,它拥有的任何ETS表都会被收获。尝试使用spawn_monitor,然后使用shell的刷新()命令来获取传入的消息。它可能会死。另一种方法是使用proc_lib模块中的工具,然后使用erl -boot start_sasl获得一些基本的崩溃错误报告,并为您的流程运行。

“裸露”的spawn(...)通常是危险的,因为如果产生的进程崩溃,您将什么也学不到。至少使用spawn_linkspawn_monitor

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19836518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档