Issue in killing the process

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Issue in killing the process

shiva
Hi all,


     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?


Regards,
Gattu shivakrishna.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Issue in killing the process

zxq9-2
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
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Issue in killing the process

Prakash Parmar-3
In reply to this post by shiva

As mentioned in exit/2 doc,


 "... If Reason is the atom normalPid does not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue. ...


use exit(whereis(Pid), Reason), where Reason will be anything than normal .


/Cheers
Prakash


From: [hidden email] <[hidden email]> on behalf of shiva <[hidden email]>
Sent: Tuesday, October 9, 2018 3:19:45 PM
To: Joe Armstrong; Erlang Questions
Subject: [erlang-questions] Issue in killing the process
 
Hi all,


     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?


Regards,
Gattu shivakrishna.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Issue in killing the process

zxq9-2
On 2018年10月9日火曜日 10時18分20秒 JST Prakash Parmar wrote:
> As mentioned in exit/2<http://erlang.org/doc/man/erlang.html#exit-2> doc,
>
>
>  "... If Reason is the atom normal, Pid does not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue. ..."
>
>
> use exit(whereis(Pid), Reason), where Reason will be anything than normal .

Indeed. Nice catch. I didn't even address the case where the process is trapping exits.

Like the old Raid commercial: "A call to `exit(Pid, kill)` kills bugs dead."

-Craig
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Issue in killing the process

Raimo Niskanen-11
On Tue, Oct 09, 2018 at 07:21:38PM +0900, [hidden email] wrote:

> On 2018年10月9日火曜日 10時18分20秒 JST Prakash Parmar wrote:
> > As mentioned in exit/2<http://erlang.org/doc/man/erlang.html#exit-2> doc,
> >
> >
> >  "... If Reason is the atom normal, Pid does not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue. ..."
> >
> >
> > use exit(whereis(Pid), Reason), where Reason will be anything than normal .
>
> Indeed. Nice catch. I didn't even address the case where the process is trapping exits.
>
> Like the old Raid commercial: "A call to `exit(Pid, kill)` kills bugs dead."
>
> -Craig

Do remember that all signals (and messages) are asynchronous, so if you
send exit(Pid, kill) the process Pid will eventually cease to exist,
albeit probably sooner than with exit(Pid, die).

To be certain that the target process no longer exists you need to monitor
its state:

    Mref = erlang:monitor(process, Pid),
    exit(Pid, die),
    receive {'DOWN',Mref,_,_,_} -> ok end,

There you have a synchronous exit, which at least in theory also should be
used for reason 'kill'...  After this you can e.g spawn a new process that
registers the same name.
This is equivalent to what the supervisors and such does.

Regards
--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions