Forum: Ruby Controlling a forked process

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9e6d05909dc733af570faadce1392e67?d=identicon&s=25 Michael Satterwhite (msatterwhite)
on 2009-02-16 05:32
If I start a process, is there some way that I can maintain control of
it. More specifically, can I start a process and then at some point
based on a user action kill that process. I see hints of that in the
documentation, but I don't see anything that specifically addresses this
case.
1bc63d01bd3fcccc36fb030a62039352?d=identicon&s=25 David Masover (Guest)
on 2009-02-16 09:22
(Received via mailing list)
Michael Satterwhite wrote:
> If I start a process, is there some way that I can maintain control of
> it. More specifically, can I start a process and then at some point
> based on a user action kill that process. I see hints of that in the
> documentation, but I don't see anything that specifically addresses this
> case.
>

Yes. The parent process should have the process ID of the child. With
that you can do things like:

if (pid = fork)
  sleep 1
  Process.kill('TERM', pid)
else
  loop do
    puts 'KILL ME'
  end
end

Or you could kill with 'KILL', if you really need it dead RIGHT NOW --
but you might want to read 'man kill' first.
9e6d05909dc733af570faadce1392e67?d=identicon&s=25 Michael Satterwhite (msatterwhite)
on 2009-02-16 19:45
David Masover wrote:

> Yes. The parent process should have the process ID of the child. With
> that you can do things like:
>
> if (pid = fork)
>   sleep 1
>   Process.kill('TERM', pid)
> else
>   loop do
>     puts 'KILL ME'
>   end
> end

on the line
     if (pid = fork)

Is fork returning the pid of the spawned process or of the current (e.g.
parent) process? More to the point, assume that I spawn multiple
processes. How can I address each of them?

Thanks
---Michael
54185df1d348bbd34587fcd4f8e4779b?d=identicon&s=25 Louis-Philippe (Guest)
on 2009-02-16 21:08
(Received via mailing list)
Hi Michael,

you can:

fork1_pid = fork { # fork 1 body }

fork2_pid = fork { # fork 2 body }

Process.kill('HUP', fork1_pid)
Process.kill('HUP', fork2_pid)

does this answer your question?

2009/2/16 Michael Satterwhite <michael@weblore.com>
9e6d05909dc733af570faadce1392e67?d=identicon&s=25 Michael Satterwhite (msatterwhite)
on 2009-02-16 21:29
Louis-Philippe wrote:

> fork1_pid = fork { # fork 1 body }
>
> fork2_pid = fork { # fork 2 body }
>
> Process.kill('HUP', fork1_pid)
> Process.kill('HUP', fork2_pid)
>
> does this answer your question?

Close ... and it may just be that I'm a bit dense today.

What is causing the first call to fork to be tied to the first process
and the second call to fork to be tied to the second process? Is it
simply that it's returning the pid of the most recently spawned process?
1bc63d01bd3fcccc36fb030a62039352?d=identicon&s=25 David Masover (Guest)
on 2009-02-16 21:31
(Received via mailing list)
Michael Satterwhite wrote:
>>   loop do
>>     puts 'KILL ME'
>>   end
>> end
>>
>
> on the line
>      if (pid = fork)
>
> Is fork returning the pid of the spawned process or of the current (e.g.
> parent) process?

It's returning the pid of the spawned process in the parent process, and
nil in the spawned process. So in the code above, the 'if' clause is in
the parent process, and the 'else' clause is in the spawned process.

> More to the point, assume that I spawn multiple
> processes. How can I address each of them?

With multiple pids. Following my pattern above, you'd do:

if pid1 = fork
  if pid2 = fork
    # parent process
  else
    # inside pid2
  end
else
  # inside pid1
end

You could also create arbitrary process trees:

if child = fork
  # parent process
elsif grandchild = fork
  # child process
else
  # grandchild process
end

Now, Louise-Philippe has some more elegant syntax, where you can pass a
block that will be executed in the spawned process. But the idea is the
same. Also worth noting, my examples above are the same relatively
low-level concept used everywhere else on Unix.

So, translating my example above:

child = fork do
  grandchild = fork do
    # grandchild process
  end
  # child process
end
# parent process
54185df1d348bbd34587fcd4f8e4779b?d=identicon&s=25 Louis-Philippe (Guest)
on 2009-02-16 22:19
(Received via mailing list)
"What is causing the first call to fork to be tied to the first process
and the second call to fork to be tied to the second process? Is it
simply that it's returning the pid of the most recently spawned process?


essentially with:

fork { # code body }

or also

fork do
  # code body
end

syntax,

you're just executing a block of code as a child process, completely
separated from its parent from the point it forks, there is no
complicated
tie over there,
the fork returns its pid when its initiated, you can then use
Process.kill
to kill it but may also want to kill it from the inside with Kernel.exit



2009/2/16 David Masover <ninja@slaphack.com>
1bc63d01bd3fcccc36fb030a62039352?d=identicon&s=25 David Masover (Guest)
on 2009-02-17 00:47
(Received via mailing list)
Michael Satterwhite wrote:
> What is causing the first call to fork to be tied to the first process
> and the second call to fork to be tied to the second process?

Because the first call to fork is both spawning and returning the
process id that was spawned.

> Is it
> simply that it's returning the pid of the most recently spawned process?
>

Close. It is returning the pid of the process that this particular call
to fork spawned.

This is effectively the same, but you're overthinking it. Let me make it
as simple as I possibly can:

this_pid = fork { this child body }

No matter where you do that in your code, or how often you do it, that
code will always do what you expect. The variable on the left will
always receive the pid corresponding to the process which is now running
the code on the right.
9e6d05909dc733af570faadce1392e67?d=identicon&s=25 Michael Satterwhite (msatterwhite)
on 2009-02-17 01:39
David Masover wrote:

> This is effectively the same, but you're overthinking it.

On that, you were right. I was separating things that are not separable.
Thank you.
This topic is locked and can not be replied to.