[erlang-questions] Issue in killing the process

zxq9@REDACTED zxq9@REDACTED
Tue Oct 9 12:15:31 CEST 2018


On 2018年10月9日火曜日 15時19分45秒 JST shiva wrote:
>      In my application, I spawned a process and registered with a name. 
> That process will do multiple rpc async calls. After making async calls, 
> I tried to kill the process using exit(whereis(process_name), normal) 
> but process is still existing and results of async call are yielded.  
> Can you please suggest how can I kill the process and results should not 
> be yielded?

There are two main ways processes are terminated normally:

1- Simply don't loop. This gives an implicit `exit(normal)`.
For example:

  loop() ->
    receive
      {print, Value} ->
        ok = io:format("Printing value: ~tp~n", [Value]),
        loop();
      retire ->
        io:format("Bye!~n");
      Unexpected ->
        ok = io:format("Unexpected message: ~tp~n", [Unexpected]),
        loop()
    end.

If you send this process a message {print, Something} it will print Something.
If you send this process a message 'retire' it will exit with the exit message 'normal' by simply failing to call loop/0 again.
If you send it anything else it will execute the unexpected message handler.
As you can see, you have all the freedom you want to write a vanilla, boring exit simply by not recursing.

If you are using gen_server (or any other OTP behavior) then you can have your handle_*/2,3 function return a tuple starting with 'stop'.


2- Have the process explicitly exit on its own by:
  * Have it call `exit(Reason)` on its own (note that the value of Reason has a system-wide meaning)
  * If the process is supervised, have it call its supervisor to terminate self():
      supervisor:terminate_child(ParentPid, self())

Consider the snippet above can become:

  loop() ->
    receive
      {print, Value} ->
        ok = io:format("Printing value: ~tp~n", [Value]),
        loop();
      {retire, Reason} ->
        io:format("Bye!~n"),
        exit(Reason);
      Unexpected ->
        ok = io:format("Unexpected message: ~tp~n", [Unexpected]),
        loop()
    end.


You *can* kill processes with exit/2, of course, but that is generally reserved for special circumstances.


All that said, the most common two ways are to have processes simply run until their tasks are complete (they end without looping or with an explicit call of `exit(normal)`) OR they run forever because they are central to the system and therefore can be left up to their supervisor to handle.

Writing projects in accordance with OTP tends to handle the second case for you. Ephemeral job workers tend to not loop if they are simply one-off parallel tasks, and if they are things like socket client handlers (or similar) then tend to explicitly terminate either with a return value of `{stop, _, _}` or exit(Reason) after doing whatever tidying up needs to be done.


Sorry, writing this in a bit of a hurry.
Hopefully I explained more than I confused.
Termination tends to either get a LOT of attention in cases where the details of it matter or no thought at all in the cases where it doesn't (by far the majority).

-Craig



More information about the erlang-questions mailing list