[erlang-questions] : Kill a process tree

June Kim <>
Mon Apr 23 14:10:59 CEST 2007


2007/4/23, Raimo Niskanen <>:
> On Mon, Apr 23, 2007 at 12:06:49AM +0900, June Kim wrote:
> > 2007/4/22, June Kim <>:
> > > My original purpose of all this is, to make a test runner, which runs
> > > a given function, which in turn might create a group of
> > > processes(which may not be linked to each other) and then kill all of
> > > them after a certain amount of time. The function under test could be
> > > written without the specific consideration of being run with the test
> > > runner.
> > >
> > > Okay. There seems to be a way out.
> > >
> > > I happened to learn that there is a way of compile-time code AST
> > > modification in Erlang. Maybe I could do something like...:
> > >  * replace all spawn/* calls with my reg_spawn/* in a specific module
> > > we want to run (and kill at once)
> > >  * In reg_spawn, we spawn a process and register the pid to a global dictionary
> > >  * after running the module, we kill all the processes that are
> > > registered in the global dictionary.
> > >
> > > So no source code modification manually. Does it sound right?
> >
> > This may work when the function only calls functions inside the
> > module. It has no control over the functions residing in other
> > modules.
> >
> > One possible solution, that I tested now, is using(or is it abusing?)
> > group_leader.
> >
>
> That would be abusing group_leader. But it can be made less abusive.
> Use a message forwarding group leader proxy.
>
> gl(OldGL) ->
>    receive X -> OldGL ! X, gl(OldGL) end.
>
> run(Fun) ->
>    OldGL = group_leader(),
>    NewGL = spawn(fun () -> gl(OldGL) end),
>    group_leader(NewGL, self()),
>    R = Fun(),
>    group_leader(OldGL, self()),
>    {NewGL,R}.
>
> This should create a new group leader that forwards all messages
> to the old group leader, call Fun() while the new group leader
> is installed, and clean up.


Thanks. That's exactly how I did this after I posted my idea about
(ab)using group leader. This simple idea of delegation hadn't hit me.

I think I have to consider Ulf's advice: trace.

>
> > -module(runner).
> > -export([run/3]).
> >
> > run(Mod,Fun,Arg)->
> >     Pid=spawn(fun run_loop/0),
> >     group_leader(Pid,Pid),
> >     Pid!{run,{Mod,Fun,Arg}},
> >     Pid.
> >
> > run_loop()->
> >     receive
> >         {run, {Mod,Fun,Arg}} ->
> >             apply(Mod,Fun,Arg),
> >             run_loop()
> >     end.
> >
> > Now I can call the tested function with run/3 and all the children and
> > grand-children processes' group_leader will be the Pid returned from
> > run/3. Then I can later kill the process group with exit(Pid,kill).
> > One undesirable side effect is all io acitivty doesn't occur. Any
> > other issues to consider?
> >
> >
> > >
> > > Where can I get more info on that "parse transform"?
> > >
> > > 2007/4/21, June Kim <>:
> > > > Sorry for my mistake,
> > > >
> > > > 2007/4/21, June Kim <>:
> > > > > If only I could programmatically replace(not search and replace on the
> > > > > source code) spawn calls in the code with spawn_link... then I may
> > > > > kill the originator process and kill all the family.
> > > >
> > > > In this case, there would be unexpected side effects: since the
> > > > processes are linked to each other, one process' death would affect
> > > > other processes, which wouldn't with the original code.
> > > >
> > > > It's more complexed.
> > > >
> > > > >
> > > > > 2007/4/21, June Kim <>:
> > > > > > 2007/4/21, Ulf Wiger (TN/EAB) <>:
> > > > > > >
> > > > > > > If the processes were linked to each other and
> > > > > > > not trapping exits, then killing the root should
> > > > > > > kill the others as well.
> > > > > > >
> > > > > > > But you claim that they are not linked...
> > > > > > > I wonder what makes it a tree, then.
> > > > > > >
> > > > > > > You could call processes(), and traverse the list
> > > > > > > looking for some common element, perhaps
> > > > > > > initial_call?
> > > > > > >
> > > > > > > E.g.
> > > > > > >
> > > > > > > 1> [P || {P,{initial_call,IC}} <-
> > > > > > >   [{P1,process_info(P1,initial_call)} ||
> > > > > > >     P1 <- processes()],
> > > > > > >     IC == {proc_lib,init_p,5}].
> > > > > > > [<0.4.0>,
> > > > > > >  <0.7.0>,
> > > > > > >  <0.9.0>,
> > > > > > >  <0.10.0>,
> > > > > > >  <0.11.0>,
> > > > > > >  <0.14.0>,
> > > > > > >  <0.16.0>,
> > > > > > >  <0.17.0>,
> > > > > > >  <0.19.0>,
> > > > > > >  <0.24.0>,
> > > > > > >  <0.25.0>,
> > > > > > >  <0.28.0>,
> > > > > > >  <0.30.0>,
> > > > > > >  <0.31.0>,
> > > > > > >  <0.32.0>,
> > > > > > >  <0.33.0>,
> > > > > > >  <0.34.0>]
> > > > > > >
> > > > > > > Without knowing anything about how the processes
> > > > > > > relate to each other, it's a bit difficult to
> > > > > > > give advice.
> > > > > > >
> > > > > > > BR,
> > > > > > > Ulf W
> > > > > >
> > > > > > Thank you for the tip but it won't work.
> > > > > >
> > > > > > What I want to do is take a abitrary function and run it as a new
> > > > > > process inside a sandbox containment and then kill all the processes
> > > > > > that originated from the function after a while.
> > > > > >
> > > > > > Maybe I'm looking for a wrong path in Erlang?
> > > > > >
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: 
> > > > > > > > [mailto:] On Behalf Of June Kim
> > > > > > > > Sent: den 20 april 2007 18:30
> > > > > > > > To: 
> > > > > > > > Subject: [erlang-questions] Kill a process tree
> > > > > > > >
> > > > > > > > Suppose I spawned a process and let's call it "root".
> > > > > > > >
> > > > > > > > root will probably spawn a few children, and those children,
> > > > > > > > in turn, would spawn a few grand-children.
> > > > > > > >
> > > > > > > > Now, I want to kill the process tree starting from root. How
> > > > > > > > can I achieve it?
> > > > > > > >
> > > > > > > > Limitation: the thing is that all the code is written using
> > > > > > > > plain spawn and no consideration was done in the code for
> > > > > > > > this kind of case(such as link). Moreover, you can't change
> > > > > > > > the code. The code for root and so on were written without
> > > > > > > > any regard for this process tree kill. (well, suppose the
> > > > > > > > root and its descendant codes were written by a third-party)
> > > > > > > >
> > > > > > > > How can I do it?
> > > > > > > >
> > > > > > > > June
> > > > > > > > _______________________________________________
> > > > > > > > erlang-questions mailing list
> > > > > > > > 
> > > > > > > > http://www.erlang.org/mailman/listinfo/erlang-questions
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://www.erlang.org/mailman/listinfo/erlang-questions
>
> --
>
> / Raimo Niskanen, Erlang/OTP, Ericsson AB
> _______________________________________________
> erlang-questions mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>



More information about the erlang-questions mailing list