|
|
 |
 |
 |
 |
Perl Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
fork() and script execution afterwards
Ive got a question about script execution after a fork() which I havnt been able to find an answer to on google yet, but Im still looking (Ive fork'd my searching :-P) I have this simple test script: ========================== #!/usr/local/bin/perl use strict; my ($pid, $x, @child, $ischild); print "BEGIN\n\n"; for ($x = 1; $x <= 5; $x++) { if (not defined($pid = fork())) { die "couldnt fork: \"$!\"\n"; } elsif ($pid) { push(@child, $pid); } else { print "This is child $x starting at " . localtime() . "\n"; sleep($x); print "Child $x terminating at " . localtime() . "\n"; exit(0); } }
foreach(@child) { waitpid($_, 0); }
1; ========================== Fiarly straight forward, and it works beautifully. My question is, for each of the child processes that are spawned, I dont see "BEGIN" outputted to the screen. Is this because the "program counter" in each of the childs continues from where it was in the parent too? The reason I ask is because Ive been trying to devise a way of executing a child process without actually beginning the whole script over again. This is because in my real script I want to perform a database query to determine just how many childs I need to fork to complete my process. But now Im beginning to wonder whether I actually need to borhter trying to avoid executing the top half of the script each time the child is spawned, if the PC continues from where it was in the parent, the child will never return to the beginning of the script. That would be so nice! :-) If this is true, where I print BEGIN I could place my database code, and replace the for loop with a while loop that runs through each database record and forks a new child if neccessary. Thanks, Tom
On May 31, 5:38 pm, "Tom Storey" <t@snnap.net> wrote: > [...] > If this is true, where I print BEGIN I could place my database code, and > replace the for loop with a while loop that runs through each database > record and forks a new child if neccessary. > Thanks, > Tom
what you want is just the way fork() works.
On Fri, 1 Jun 2007 00:08:53 +0930, "Tom Storey" <t @snnap.net> wrote: >My question is, for each of the child processes that are spawned, I dont see >"BEGIN" outputted to the screen. Well, only ONE "BEGIN" should be printed, since it is *before* the fork(). Or am I missing something? Michele -- {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
Andrew Fedyashov <andrew.fedyas @gmail.com> wrote: > On May 31, 5:38 pm, "Tom Storey" <t @snnap.net> wrote: > > [...] > > If this is true, where I print BEGIN I could place my database code, > > and replace the for loop with a while loop that runs through each > > database record and forks a new child if neccessary. > > Thanks, > > Tom > what you want is just the way fork() works.
Yep. But one thing to look out for, is that the forked children may screw up the parent's database connection. If the connection isn't needed after the fork, the parent should disconnect before it forks. It if it is needed, it might still be best for the parent to disconnect and then reconnect after the forks, or if that is not convenient, than setting InactiveDestroy in the children may be necessary. If the children themselves need connections, they should initiate them after the fork, and *not* try to use the one they inherited from the parent. -- -------------------- http://NewsReader.Com/ -------------------- Usenet Newsgroup Service $9.95/Month 30GB
"Michele Dondi" <bik.m @tiscalinet.it> wrote in message news:loot535k7fsjnieh9bbr09do9er9lrh5lj@4ax.com... > On Fri, 1 Jun 2007 00:08:53 +0930, "Tom Storey" <t @snnap.net> wrote: > >My question is, for each of the child processes that are spawned, I dont see > >"BEGIN" outputted to the screen. > Well, only ONE "BEGIN" should be printed, since it is *before* the > fork(). Or am I missing something?
That was my question, whether or not the child continues to execute from where it forked in the parent, which seems as though it is the case.
> Michele > -- > {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr > (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' > .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, > 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
<xhos @gmail.com> wrote in message news:20070531111545.141$FX@newsreader.com...
> Andrew Fedyashov <andrew.fedyas @gmail.com> wrote: > > On May 31, 5:38 pm, "Tom Storey" <t @snnap.net> wrote: > > > [...] > > > If this is true, where I print BEGIN I could place my database code, > > > and replace the for loop with a while loop that runs through each > > > database record and forks a new child if neccessary. > > > Thanks, > > > Tom > > what you want is just the way fork() works. > Yep. > But one thing to look out for, is that the forked children may screw up the > parent's database connection. If the connection isn't needed after the > fork, the parent should disconnect before it forks. It if it is needed, it > might still be best for the parent to disconnect and then reconnect after > the forks, or if that is not convenient, than setting InactiveDestroy in > the children may be necessary. If the children themselves need > connections, they should initiate them after the fork, and *not* try to use > the one they inherited from the parent.
Hm excellent, thanks for the tips. The children *will* need a database connection, but they wont need to use the original connection which the parent uses. I thought about disconnecting from the original database as the very first line of code after forking, then establishing a new database connection for the child to use as I figured there might be some issues. In any case, I'll have to give it a try and see what happens. Thanks again.
> -- > -------------------- http://NewsReader.Com/ -------------------- > Usenet Newsgroup Service $9.95/Month 30GB
"Tom Storey" <t @snnap.net> wrote in message news:135ur0e61bvccdd@corp.supernews.com... > "Michele Dondi" <bik.m@tiscalinet.it> wrote in message > news:loot535k7fsjnieh9bbr09do9er9lrh5lj@4ax.com... > > On Fri, 1 Jun 2007 00:08:53 +0930, "Tom Storey" <t@snnap.net> wrote: > > >My question is, for each of the child processes that are spawned, I dont > see > > >"BEGIN" outputted to the screen. > > Well, only ONE "BEGIN" should be printed, since it is *before* the > > fork(). Or am I missing something? > That was my question, whether or not the child continues to execute from > where it forked in the parent, which seems as though it is the case.
... in which case, yes I should only be seeing one BEGIN because that piece of code only ever gets executed once. :-)
> > Michele > > -- > > {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr > > (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' > > .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, > > 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
Tom Storey wrote: > That was my question, whether or not the child continues to execute from > where it forked in the parent, which seems as though it is the case.
It's not "which seems". It is documented. That is exactly how fork() works. It is a system call that is called once and returns twice, resuming right where it left off. The first return is in the parent process and the value returned is the PID of the child process. The second return is in the child process and the returned value is 0. The child process is created by cloning the parent's virtual memory, variables, file descriptors, etc. Including the stack, the return addresses on the stack, and the Program Counter for returning to user-mode when leaving kernel-mode. What gave you the impression that fork() would start over from the top? -Joe
"Joe Smith" <j @inwap.com> wrote in message news:TqCdneW6sJ-XLsLbnZ2dnUVZ_qarnZ2d@comcast.com... > Tom Storey wrote: > > That was my question, whether or not the child continues to execute from > > where it forked in the parent, which seems as though it is the case. > It's not "which seems". It is documented. That is exactly how fork() > works. It is a system call that is called once and returns twice, > resuming right where it left off.
Based on my prior knowledge of the subject, it "seemed" as though it would resume from where it forked. > The first return is in the parent process and the value returned is > the PID of the child process. The second return is in the child > process and the returned value is 0.
Aware of that already. > The child process is created by cloning the parent's virtual memory, > variables, file descriptors, etc. Including the stack, the return > addresses on the stack, and the Program Counter for returning to > user-mode when leaving kernel-mode.
I had a basic idea that variables etc would be copied, but what was to happen with the PC was unknown to me based on what I wrote below... > What gave you the impression that fork() would start over from the top? > -Joe
This is the first time Ive ever written something that uses the fork() command, and since I hadnt found any documentation that described whether it would start over or resume from where it forked, what what I to assume? (I'd rather not assume anything, but after getting no where and searching around for decent examples or documentation I figured it was time to ask more knowledgeable persons.) But now I know, and I can get on with my code. Thanks, Tom
"Tom Storey" <t @snnap.net> writes: > This is the first time Ive ever written something that uses the fork() > command, and since I hadnt found any documentation that described whether it > would start over or resume from where it forked The first line of the docs for the fork() function says "Does a fork(2) system call to create a new process running the same program at the same point." If you couldn't find the first sentence in the docs for the function you're using, you weren't looking very hard. sherm-- -- Web Hosting by West Virginians, for West Virginians: http://wv-www.net Cocoa programming in Perl: http://camelbones.sourceforge.net
On Fri, 1 Jun 2007 10:14:54 +0930, "Tom Storey" <t @snnap.net> wrote: >> Well, only ONE "BEGIN" should be printed, since it is *before* the >> fork(). Or am I missing something? >That was my question, whether or not the child continues to execute from >where it forked in the parent, which seems as though it is the case.
Oh sorry: yes, *this is the case*. Since you seemed confident enough with it (as opposed to clueless n00bz,) I thought it was obvious. Michele -- {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
"Sherm Pendley" <spamt @dot-app.org> wrote in message news:m2ps4g2nxz.fsf@local.wv-www.com... > "Tom Storey" <t @snnap.net> writes: > > This is the first time Ive ever written something that uses the fork() > > command, and since I hadnt found any documentation that described whether it > > would start over or resume from where it forked > The first line of the docs for the fork() function says "Does a fork(2) system > call to create a new process running the same program at the same point." > If you couldn't find the first sentence in the docs for the function you're > using, you weren't looking very hard.
I hadnt seen that particular piece of documentation.
On Fri, 1 Jun 2007 15:42:43 +0930, "Tom Storey" <t @snnap.net> wrote: >> What gave you the impression that fork() would start over from the top? >> -Joe >This is the first time Ive ever written something that uses the fork() >command, and since I hadnt found any documentation that described whether it >would start over or resume from where it forked, what what I to assume?
Well, if you're under *NIX you probably can access the fork(2) manpage simply by issuing the man fork shell command. That is the C library's fork() which maps directly to the corresponding system call. By contrast, Perl's fork() is a wrapper around it, with quite similar functionality. You can access the documentation of all Perl functions with perldoc. In this case: perldoc -f fork HTH, Michele -- {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
"Tom Storey" <t @snnap.net> writes: > "Sherm Pendley" <spamt @dot-app.org> wrote in message > news:m2ps4g2nxz.fsf@local.wv-www.com... > If you couldn't find the first sentence in the docs for the > function you're using, you weren't looking very hard. > I hadnt seen that particular piece of documentation.
That's unfortunate, since it's on your hard drive, and is a much more authoritative source than guessing. :) If you're ever curious about the behaviour of any Perl function, you have only to type perldoc -f $function_name at a command line, and there you go. If you're running Windows, there are also nicely-formatted help files available from your Start menu, but as I don't happen to run Windows myself, I can't direct you further, except to note that all the Perl docs are there somewhere. I urge you to become familiar with perldoc, in particular, you should at the very least skim the output of perldoc perltoc and I would make time as soon as possible to read the FAQ sections there, since it will be the most up-to-date and correct documentation for the version of Perl on your hard drive. I know it seems like a lot, but at least familiarizing yourself with what's in the FAQ lets you search it first, which will not only be a lot faster than posting to USENET and waiting for a reply, but will save you from annoying the most helpful people on clpm, who are tired of being asked to read the FAQ for someone else. :) Perl's built-in documentation is really quite impressive; much better than that of most other languages. You'd do yourself a real service to become familiar with it. -=Eric
On 01 Jun 2007 10:04:00 -0600, Eric Schwartz <emsch@pobox.com> wrote: >authoritative source than guessing. :) If you're ever curious about >the behaviour of any Perl function, you have only to type >perldoc -f $function_name >at a command line, and there you go. If you're running Windows, there
That's what I told him too. But OTOH perldoc -f fork refers to fork(2) and that is most probably not on his system if he uses Windows. Michele -- {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
Michele Dondi <bik.m @tiscalinet.it> writes: > That's what I told him too. But OTOH > perldoc -f fork > refers to fork(2) and that is most probably not on his system if he > uses Windows.
As that may be; however, it does explain the semantics well enough I don't imagine one would need to read fork(2) for most purposes. -=Eric
On 01 Jun 2007 12:20:12 -0600, Eric Schwartz <emsch@pobox.com> wrote: >> refers to fork(2) and that is most probably not on his system if he >> uses Windows. >As that may be; however, it does explain the semantics well enough I >don't imagine one would need to read fork(2) for most purposes.
Really, I'm reading it now and I find it doesn't explain it that well: it's obvious to me that execution will resume in both parent and child after the fork(), also because any other option wouldn't make sense IMHO, but it is *never* said so and a complete n00b may actually get it wrong... Michele -- {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB=' .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_, 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
|
 |
 |
 |
 |
|