kleinbiker7 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to write an application that displays data on the screen, or emails the data to the sender, if there is a lot of data to display. For the email part, I fork off a process so that the child does all the data gathering, while the parent merely displays a message, and is supposed to quit.

But it doesnt. The child does his thing, but the stupid parent keeps waiting for the child to finish.

Anyway, here is my code sample:

# %form is a hash that contains all the values # that the person entered on the form. It is global # IF THE USER SELECTED EMAIL..DO THIS CODE if ($form{attachme} eq "yes") { $query =~ s/(and|or)$//; # Strip off trailing AND/OR my ($values, $pid); if ($pid = fork) { # Send the data by email if option selected # The 'Search Was Successful' note has been moved to # the correct directory on the hard drive # and the script redirects the user to that page. # This is to stop HTTPD from hanging. # users'printvtml is just like vtml'printvtml, EXCEPT that the # Content Type text/html line has been replaced with a Locatio +n header # to redirect the user to the note saying that the email has b +een sent. $form{-nextpage} = "/admin/users/reports/mailview.vtml"; # This is a function that we use to print to the screen. # It is not causing this problem. &users'printvtml($URLPREFIX."$form{-nextpage}",\%form,\%script +); exit (0); } elsif (defined $pid) { # CHILD PROCESS GOES HERE if ( $form{which} eq "custom" ) { $values = $form{retval}; } elsif ( $form{which} eq "all" ) { $values = $form{allval}; } exec ("perl $fork_to $form{sendto} \"$query\" $values"); exit (0); } exit (0); }

Edit by tye

  • Comment on How do you tell the parent process to stop it's HTTP transfer, when it forks off a child process?
  • Download Code

Replies are listed 'Best First'.
Re: How do you tell the parent process to stop it's HTTP transfer, when it forks off a child process?
by suaveant (Parson) on May 30, 2001 at 17:37 UTC
    if you do a close STDOUT; at the start of the child, I believe that will solve your problem. Apache won't quit till it sees no more STDOUTs to read from... I don't think you need to close STDERR.
                    - Ant
Re: How do you tell the parent process to stop it's HTTP transfer, when it forks off a child process?
by shotgunefx (Parson) on May 30, 2001 at 17:44 UTC
    There was a node about this recently. I believe the only way you will get it to work is to close STDOUT.

    -Lee

    "To be civilized is to deny one's nature."
Re: How do you tell the parent process to stop it's HTTP transfer, when it forks off a child process?
by Anonymous Monk on May 31, 2001 at 02:05 UTC
    Have you tried to display the web page first (you can include the Content-Length header, so that client knows how much to expect in the reply), then do the email stuff. This way you don't need a fork.
Re: (petethered) How do you tell the parent process to stop it's HTTP transfer, when it forks off a child process?
by Anonymous Monk on May 31, 2001 at 05:18 UTC
    I use forking alot for intense SQL queries when the results of the queries doesnt matter to the user.

    There are two ways to do the forking that Ive found that fixes your problem.

    Method one: Fork with a location tag. Once the browsers receive the location tag they go away without waiting.

    Example:

    #!/usr/bin/perl # # do pre fork stuff here # if (fork) { # # Damn browser, go away! # print "Location: http://www.wherever.com/blah\n\n"; exit; } # # do post forking stuff here #

    Method two: Disable buffering and then close STDOUT.

    Example:

    #!/usr/bin/perl # #disable buffering # $| = 1; # # prefork stuff # if (fork) { # # stuff to display to user. other processing that # the user needs to see, ect. # print "Content-type: text/html\n\n"; print "Done"; } # # Close STDOUT; # close STDOUT; # # work in the background #

    Pete

    insert into pete('red hair','green eyes','overinflated ego');

      DAMN, posted the above as anonymous by accident ;(

      Pete

      insert into pete('red hair','green eyes','overinflated ego');