The documentation for forkperlipc, as pointed out by McA below, has an example of using a hash to store all of the PIDs that have been stared. You may want to study that example.
So, you can think of it this way. A global scalar variable in the parent is like a bucket that can only hold one thing. Every time that you assign to that variable, perl dumps what is currently in the bucket, and puts the new thing into the bucket. Therefore, only the last child PID will be available to your parent process, at least in the way you currently have it implemented.
A hash is like a pegboard, where you can hang many things off from the single hash variable. It differs from the bucket analogy above by storing the pegboard in the variable instead of storing a thing in the variable.
note: not happy with the analogy - best available between my ears at the moment.
| [reply] |
Keep in mind that perl fork does not return -1, it returns undef on failure. In your code, fork failure results in system() and exit() on the parent side. A useful idiom with fork is my $pid = fork() // die; you may want if (!defined $pid) {} else if ($pid) {} else {}.
Keep in mind that a call to system results in another fork and wait, hence your work runs in a child of a child. You may have intended a direct exec instead of system.
Your OP question is somewhat ambiguous. Just in case, I'll mention that there is no guarantee that a newly spawned child has a different pid from some earlier (already reaped) process. Pid numbers are recycled.
| [reply] [d/l] [select] |
I like your response a lot, because it makes perfect sense. So, in my case, I want to execute a separate script in the child process (which is the system call in the code posted). My while loop continuously grabs commands from a mysql database. In the event that a stop command is encountered, my loop will kill the child process, stopping the script that was started with a 'start' command. I agree you that a system command may be unnecessary in this case. But, with an exec call, I don't think it returns a child ID, so how would I keep track of the script and end it when the command comes in?
General Question:
When I call system, there is an implicit wait call until the child finishes?
An Approach:
I think someone mentioned that an array would be useful, to keep track of the child pid's. I am trying that route, because it may work in my case. Thoughts?
| [reply] |
General Question: When I call system, there is an implicit wait call until the child finishes?
Yes. See "perldoc -f system"
| [reply] |
yes, but this doesn't fork "multiple times"... | [reply] |
| [reply] |
I think you're going to want more than a single scalar. A hash or an array would be a better fit. You at best have a one-to-many relationship here of one parent and many children. At worst you have a tree of processes with children, grandchildren, etc.
The really bad part is there's no way for us to reason about what that structure is without seeing the loop.
There's a thread on Usenet (well, archived on Google Groups actually) I'd recommend. Fork lots of children as well as merlyn's articles listed there ( Forking Parallel Link Checker and Getting Your Kids To Do The Work).
One thing to remember is you have data in the parent about the children and data in the children about the parent, but you don't have any trustworthy data about the children in the other children. Another is that you don't automatically have a good way to communicate among the processes just because they are related.
| [reply] |