Controlling a forked process

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.

Michael S. 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.

David M. 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

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 S. [email protected]

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?

Michael S. 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

Michael S. 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.

"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 M. [email protected]

David M. 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.