2010-12-03 12 views
5

スーパープロセスに子プロセスを開始するように指示するロジックモジュールがあります。私はそれらの子供たちを論理モジュールの状態で保存する必要があります。しかし、スーパバイザが再起動した場合、子のpidも更新する必要があります。start_childコールを開始したプロセスで子プロセスを登録する

私はstart_child呼び出しからの戻り値pidを使用できません。これは、最初の開始時にpidだけを返し、再起動はしません。今は、子プロセスが、子モジュールのinit関数から論理モジュール内のレジスタ関数(新しいPIDで状態を更新)を呼び出すようにします。こうすることで、プロセスが再起動されるたびに、論理モジュールはその状態のpidを更新できます。ロジックモジュールはgen_serverで、私は子プロセスを登録するときにキャストを行います。

誰もがこの問題を見ることができますし、それを行うための他の "適切な"方法がありますか?

答えて

6

1つの問題は、あなたがChildPidを持っていて、その子供が今や死んでいる可能性があることです。したがって、castでメッセージを送信すると、メッセージが失われている可能性があります。 callからそれをキャッチしない限り、callを通してあなたは{'EXIT', noproc}で自分自身をクラッシュさせます。あなたの解決策は、あなたがメッセージを送信した瞬間にPidが長く消え去ったことを考慮に入れなければなりません。通常、メッセージが失われたことを無視することによって、自分自身をクラッシュさせたり、問題を解決してから続行したりします。

いくつかのオプションがあります。これはゆるいリストです:

  • あなたはそうします。子供たちが自分自身を登録させる。
  • ロジックモジュールに子にmonitorがあるようにします。そうすれば死ぬかどうか分かる。
  • 使用Erlangのソリューションgprocモジュール:https://github.com/esl/gprocあなたの情報を追跡するETSテーブルにきちんとしたインターフェースを提供します。 gprocでpidを調べることができ、がプロセスがちょうど再開している場合は到着を待つことに注意してください。
  • supervisor:which_childrenを使用して該当する子を見つけます。 gproc
  • ローカル名前のバリエーションとして、独自のETSテーブルは原子である必要はあり
  • ロールが、グローバルに登録名前は(彼らはgproc年代のように、やや探しETSテーブルに内部的に保存されている任意の用語することができ、参照グローバル名_サーバーkernel/stdlib)。グローバル構造を使用して問題のpidを追跡します。
関連する問題