timer_server という名前の gen_server により、タイマー モジュール関数が返されなくなりました

StackOverflow https://stackoverflow.com/questions/500169

  •  20-08-2019
  •  | 
  •  

質問

を生成するスーパーバイザを作成しました。 gen_server 私は電話した timer_server. 。この仕事の一つは、 timer_serverは登録と通話を管理することです timer:send_interval 一定の間隔で pid にメッセージを送信します。

ただし、最初の部分では、 gen_server, 、私が電話するところ timer:send_interval ロックアップになってしまいました。ドキュメントにはタイマーについて次のように書かれていました。関数はすぐに戻るので、これは非常に厄介でした。

名前を変更したとき gen_serverrecord_timer_server この問題は解決しました。私の質問は 2 つあります:

  1. 登録済みプロセスを作成できるのはなぜですか timer_server, 、すでに存在していた場合 timer:start() 起動中のアプリケーションによって呼び出されましたか?
  2. 一度開始すると、この関数が私の名前を呼び出すのであれば、なぜ名前の検索で不正一致が発生しないのでしょうか。 timer_server を使用して send_interval 関数?

コードは必要ないと思いますが、リクエストがあれば更新してコードを追加できます。

役に立ちましたか?

解決

このタイマーへの呼び出しでハング以下のようにして、簡単に再作成することができます。send_intervalを

1> register(timer_server, self()).
true
2> timer:send_interval(5000, self(), hello).

これは失敗したものの...

1> timer:send_interval(5000, self(), hello).
{ok,{interval,#Ref<0.0.0.32>}}
2> register(timer_server, self()).
** exited: {badarg,[{erlang,register,[timer_server,<0.30.0>]},

だから、タイマーの最初の呼び出しがtimer_serverと呼ばれるプロセスを開始しようとしているようですし、あなたが最初にこの名前を取った場合はハングアップします。

それがハング理由としてtimer.erlを行います。

ensure_started() ->
    case whereis(timer_server) of
        undefined -> 
            C = {timer_server, {?MODULE, start_link, []}, permanent, 1000, 
                worker, [?MODULE]}
            supervisor:start_child(kernel_safe_sup, C),  % kernel_safe_sup
            ok;
        _ -> ok
    end.

細かい返す、gen_serverが続く:timer_serverに呼び出します。あなたのプロセスは、自身が応答するのを待っ立ち往生ます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top