Elixir-processes
Elixir-プロセス
Elixirでは、すべてのコードはプロセス内で実行されます。 プロセスは互いに分離され、互いに並行して実行され、メッセージパッシングを介して通信します。 Elixirのプロセスをオペレーティングシステムのプロセスと混同しないでください。 Elixirのプロセスは、メモリとCPUの点で非常に軽量です(他の多くのプログラミング言語のスレッドとは異なります)。 このため、数万または数十万ものプロセスが同時に実行されることも珍しくありません。
この章では、新しいプロセスを生成し、異なるプロセス間でメッセージを送受信するための基本的な構成について学習します。
スポーン関数
新しいプロセスを作成する最も簡単な方法は、 spawn 関数を使用することです。 spawn は、新しいプロセスで実行される関数を受け入れます。 たとえば-
上記のプログラムが実行されると、次の結果が生成されます-
spawn関数の戻り値はPIDです。 これはプロセスの一意の識別子であるため、PIDの上でコードを実行すると、異なるコードになります。 この例でわかるように、プロセスが生きているかどうかを確認すると、プロセスは停止しています。 これは、指定された関数の実行が終了するとすぐにプロセスが終了するためです。
既に述べたように、すべてのElixirコードはプロセス内で実行されます。 自己機能を実行すると、現在のセッションのPIDが表示されます-
上記のプログラムを実行すると、次の結果が生成されます-
メッセージの受け渡し
メッセージを send でプロセスに送信し、 receive で受信できます。 現在のプロセスにメッセージを渡し、同じプロセスで受信してみましょう。
上記のプログラムが実行されると、次の結果が生成されます-
send関数を使用して現在のプロセスにメッセージを送信し、selfのPIDに渡しました。 次に、 receive 関数を使用して着信メッセージを処理しました。
メッセージがプロセスに送信されると、メッセージは*プロセスメールボックス*に保存されます。 受信ブロックは、現在のプロセスメールボックスを通過して、指定されたパターンのいずれかに一致するメッセージを検索します。 受信ブロックは、ガードや、caseなどの多くの句をサポートしています。
パターンのいずれかに一致するメールボックスにメッセージがない場合、現在のプロセスは一致するメッセージが到着するまで待機します。 タイムアウトも指定できます。 例えば、
上記のプログラムが実行されると、次の結果が生成されます-
注-メッセージがすでにメールボックスにあると予想される場合、0のタイムアウトを指定できます。
リンク集
Elixirでの最も一般的なスポーン形式は、実際には spawn_link 関数によるものです。 spawn_linkの例を見る前に、プロセスが失敗したときに何が起こるかを理解しましょう。
上記のプログラムを実行すると、次のエラーが生成されます-
エラーをログに記録しましたが、生成プロセスはまだ実行中です。 これは、プロセスが分離されているためです。 あるプロセスの失敗を別のプロセスに伝播させるには、それらをリンクする必要があります。 これは、 spawn_link 関数を使用して実行できます。 同じことを理解するための例を考えてみましょう-
上記のプログラムを実行すると、次のエラーが生成されます-
これを iex シェルで実行している場合、シェルはこのエラーを処理し、終了しません。 ただし、最初にスクリプトファイルを作成してから elixir <file-name> .exs を使用して実行した場合、このエラーにより親プロセスも停止します。
フォールトトレラントシステムを構築するとき、プロセスとリンクは重要な役割を果たします。 Elixirアプリケーションでは、しばしばプロセスをスーパーバイザーにリンクします。スーパーバイザーは、プロセスが終了したときを検出し、その場所で新しいプロセスを開始します。 これは、プロセスが分離されており、デフォルトでは何も共有しないためにのみ可能です。 プロセスは分離されているため、プロセスの障害がクラッシュしたり、別のプロセスの状態を破壊したりすることはありません。 他の言語では、例外をキャッチ/処理する必要があります。 Elixirでは、スーパーバイザーがシステムを適切に再起動することを期待しているため、実際にプロセスを失敗させても問題ありません。
状態
たとえば、アプリケーション構成を保持するために状態を必要とするアプリケーションを構築する場合、またはファイルを解析してメモリに保持する必要がある場合、どこに保存しますか? Elixirのプロセス機能は、このようなことを行うときに便利です。
無限にループし、状態を維持し、メッセージを送受信するプロセスを作成できます。 例として、 kv.exs という名前のファイルにキーと値のストアとして機能する新しいプロセスを開始するモジュールを作成してみましょう。
私たちは今、次を実行しましょう-
これで、 iex シェルになっているはずです。 私たちのモジュールをテストするには、次を試してください-
上記のプログラムが実行されると、次の結果が生成されます-