fork does nothing to redirect stdin, stdout and stderr while popen in
the form you used will send the sub process's stdout to a pipe. So
the answer is: no, they are not equivalent. Rather popen uses some
form of fork under the hood.
Kind regards
robert
···
2009/12/29 Nilez Parker <dcparker@gmail.com>:
I just want to know if the following two are technically equivalent
(calling fork(2) in UNIX environments):
##########
IO.popen('-') {|io|
...
}
#---------
fork do
...
end
##########
As much explanation you want to give will be appreciated, I will soak it
all up. Thanks ahead.
fork does nothing to redirect stdin, stdout and stderr while popen in
the form you used will send the sub process's stdout to a pipe. So
the answer is: no, they are not equivalent. Rather popen uses some
form of fork under the hood.
Thanks Robert. I think I meant to ask whether Process.popen uses the
same OS fork call as Process.fork does.
I found what I need for now though, so I'm posting it partly just for
people who find this via google later on. I wanted some pipes between
parent and children, and this is what I came up with:
children =
3.times do
from_child, to_parent = IO.pipe
from_parent, to_child = IO.pipe
fork do
# don't need to read from or write to child
to_child.close
from_child.close
to_parent.write "READY"
loop { ... }
end
children << to_child
# don't need to read from or write to parent
to_parent.close
from_parent.close
end
# Now the parent has a read/write IO pair for each child stored in
`children'; each child has a read/write IO pair for the parent.
Thanks Robert for the quick answer, and I'm still curious whether
Process.popen uses the same OS fork call as Process.fork does.
fork does nothing to redirect stdin, stdout and stderr while popen in
the form you used will send the sub process's stdout to a pipe. So
the answer is: no, they are not equivalent. Rather popen uses some
form of fork under the hood.
Thanks Robert. I think I meant to ask whether Process.popen uses the same OS fork call as Process.fork does.
I found what I need for now though, so I'm posting it partly just for people who find this via google later on. I wanted some pipes between parent and children, and this is what I came up with:
children =
3.times do
from_child, to_parent = IO.pipe
from_parent, to_child = IO.pipe
fork do
# don't need to read from or write to child
to_child.close
from_child.close
to_parent.write "READY"
loop { ... }
end
children << to_child
# don't need to read from or write to parent
to_parent.close
from_parent.close
end
# Now the parent has a read/write IO pair for each child stored in `children'; each child has a read/write IO pair for the parent.
I don't see why you go through this instead using one of the #popen family of methods (there is also #popen3).
Thanks Robert for the quick answer, and I'm still curious whether Process.popen uses the same OS fork call as Process.fork does.
I don't see why you go through this instead using one of the #popen
family of methods (there is also #popen3).
Thanks again .. but I've looked around at the docs and I don't see how I
could accomplish the same thing as my example code. Perhaps the main
problem is that with popen* the parent process goes into the block too,
and its pipes with the child are closed when it leaves the block. This
is a problem because I need to start several child forks and be able to
communicate with them all, and then start and stop them at will from
there. Any pointers as to how I can / should use popen, or popen2, or
popen3?
If you don't pass a block to IO#popen, it just returns the IO object.
popen3() works similarly.
Gary Wright
···
On Dec 29, 2009, at 6:03 PM, Nilez Parker wrote:
I don't see why you go through this instead using one of the #popen
family of methods (there is also #popen3).
Thanks again .. but I've looked around at the docs and I don't see how I
could accomplish the same thing as my example code. Perhaps the main
problem is that with popen* the parent process goes into the block too,
and its pipes with the child are closed when it leaves the block. This
is a problem because I need to start several child forks and be able to
communicate with them all, and then start and stop them at will from
there. Any pointers as to how I can / should use popen, or popen2, or
popen3?