クライアントプロセスがデータを送信するときにデータをファイルに記録するgen_serverモジュールがあります。2つのクライアントプロセスがこのモジュールに同時にデータを送信するとどうなりますか?ファイル操作は互いに競合しますか?erlangのドキュメントはここではイライラするほど不明確です。
4 に答える
すべてのErlangプロセスはメッセージキューを維持します。プロセスはメッセージをフェッチし、メッセージを1つずつ処理します。
この例では、2つのクライアントがgen_server
同時に呼び出した場合、これらの呼び出しはgen_server
プロセスのキュー内のメッセージになり、gen_server
はこれらのメッセージを1つずつ処理します。したがって、競合について心配する必要はありません。
ただし、1つのプロセスが他のプロセスからのメッセージを処理しなければならない場合は、プロセスの容量を検討して設計を最適化する必要があります。そうしないと、ボトルネックになります。
はgen_server
クライアントプロセスとは別のプロセスで実行されるため、call
/cast
を実行すると、実際にはサーバープロセスにメッセージが送信されます。
すべてのメッセージはプロセスのメッセージキューに配置され、プロセスはメッセージを1つずつ処理します。プロセスがビジー状態のときにメッセージが到着すると、そのメッセージはメッセージキューに入れられます。したがって、同時に到着するログメッセージは、順番に処理されるため、互いに干渉することはありません。
これはそれ自体のプロパティではなくgen_server
、erlangのすべてのプロセスの一般的なプロパティであるため、gen_serverのドキュメントではこれについて言及されていません。
gen_serverは、1つのプロセスまたは複数のプロセスから実行されたかどうかに関係なく、要求が実行された順序で要求を処理するだけです。
ログに書き込む場合、競合状態を心配する必要はありません。
幸い、OTPのソースはgithubですぐに利用できますが、簡単な答えは、gen_serverがループで実行され、受信した順序で要求に応答し、あるタイプ(handle_cast、handle_call、またはhandle_info)が別のタイプよりも優先されないことです。
gen_serverプロセスは、キュー内の次のキャスト/呼び出し/情報を処理する前に戻る必要があるため、handle_callの使用は潜在的に問題になる可能性があります。たとえば、handle_callでは、self()を使用してgen_server:callを回避します。