5

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

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

誰かがこれに関する問題を見ることができますか、そしてそれを行う他の「適切な」方法はありますか?

4

1 に答える 1

6

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

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

  • あなたがするようにしてください。子供たちに自分自身を登録させます。
  • ロジックモジュールmonitorに子を持たせます。そうすれば、それが死ぬかどうかがわかります。
  • Erlang Solutions のgprocモジュールを使用してください: https ://github.com/esl/gprocこれは、情報を追跡するETSテーブルへのきちんとしたインターフェースを提供します。プロセスが再起動している場合は、gprocでpidを検索し、その到着を待つことができることに注意してください。
  • supervisor:which_children関連する子を見つけるために使用します。
  • のバリアントとして独自のETSテーブルをロールしますgproc
  • ローカル名はアトムである必要がありますが、グローバルに登録された名前は任意の用語にすることができます(gprocのように見えるETSテーブルに内部的に格納されます。のglobal_name_serverを参照してくださいkernel/stdlib)。グローバル構造を使用して、問題のpidを追跡します。
于 2010-12-03T18:07:15.897 に答える