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.

···

--
Posted via http://www.ruby-forum.com/.

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.

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

···

--
Posted via http://www.ruby-forum.com/\.

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>

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
--
Posted via http://www.ruby-forum.com/\.

Michael Satterwhite wrote:

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?

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

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?

···

--
Posted via http://www.ruby-forum.com/\.

"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>

Michael Satterwhite wrote:

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?

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

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.

···

--
Posted via http://www.ruby-forum.com/\.