2012-03-05 9 views
1

gen_fsm timeout에 대한 질문이 있습니다. 두 가지 상태를 가진 gen_fsm 집합이 있다고 가정 해 봅시다 (나중에 더 많은 상태가 될 수 있음) : idle은 시작 상태이고 working입니다.gen_fsm erlang timeout

5 초마다 gen_fsm이 특정 매개 변수를 검사하고 이에 따라 idle에 남아 있거나 working으로 이동합니다. gen_fsm이 working으로 이동할 때마다 을 사용하여 다른 모든 gen_fsm에 메시지를 보냅니다. idle의 메시지는 working으로, working의 메시지는 수신 메시지를 신경 쓰지 않아야합니다.

요점은 상태 제한 시간에 왜곡이 들기를 원하지 않는다는 것입니다 (예 : 기기가 working에 3 초 동안 있고 메시지를 수신하면 어떻게됩니까?) 5 초 타임 아웃은 더 이상 유효하지 않으며, (고정 된 시간에 타임 아웃 메시지를 발생시켜야 함을 의미합니다.)

now()time:now_diff/2을 사용하는 내 솔루션의 주요 부분은 다음과 같습니다. 작은 드리프트가 있습니다. 여하튼, 초 단위로 이야기 한 이래로 공정한 것처럼 보입니다.

당신은 그것이 유효하다고 생각하십니까?

{ok, idle, #state{time = now()}, 5000}. 

idle(timeout, State) -> 
    %% do some operations 
    {next_state, idle, State#state{time = now()}, 5000}. 

working(timeout, State) -> 
    %% do some other actions 
    {next_state, working, State#state{time = now()}, 5000}. 

handle_event(work, working, #state{time = Time} = State) -> 
    Timeout = round(timer:now_diff(now(), Time)/1000), 
    {next_state, working, State, Timeout}. 

handle_event(work, StateName, state{time = Time} = State) -> 
    Timeout = round(timer:now_diff(now(), Time)/1000), 
    {next_state, working, State, Timeout}. 

답변

4

timer:apply_interval 중 하나를 사용하여 이벤트를 fsm으로 보내는 API 함수를 호출 할 수 있습니다.

timer:send_interval을 사용하면 gen_fsm의 handle_info 콜백에서 처리 할 수있는 사용자 지정 메시지를 보낼 수 있습니다.

+0

사실 각 상태 gen_fsm : send_event_after (5000, timeout)에서 코드를 변경했습니다. 이거 어떻게 생각해? – user601836

+0

이것은 IMHO의 단점을 가지고 있습니다. 고정 된 간격을 유지하려면 항상 현재 시간을 수정해야합니다. 타이머 : * _ interval 함수가이를 무료로 올바르게 수행합니다. –