This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Perl failure


On Jul 18 17:45, Bruce Dobrin wrote:
> Hi,  
> I stripped down the code to a small testable bit.  The problem seems to
> occur when I reach 256 forks on a cygwin1.5.18 or 19 but not on my
> cygwin1.5.5. win2k system.  The original code give the forked process
> time to finish,  but it still looks like it eats it after about 256
> iterations  ( it actually failed between 259 and 252 iterations,  but
> it's pretty complicated so I'm not sure what else was happening).
> 
> Here is my test code:
> dobrin@tiburon:/tmp> cat test8.pl 
> ################
> #!/usr/bin/perl -w
> 
> use strict;
> my $pid;
> 
> foreach my $incr (`seq 1 1 800`) {
>          
>                     unless (defined ($pid = fork)) {
>                          die " cannot fork $!";
>                      }
>                     unless ($pid) {
>                       print " the sequence is $incr \n";
>                       exit;
>                     }
>              print "pid is $pid\n";
>            }
> 
> ###############
> 
> The error here is :
> cannot fork Resource temporarily unavailable at ./test8.pl line 11.
> panic: MUTEX_LOCK (45) [op.c:354].
> 
> On cygwin1.5.5 it finishes successfully.  I'm not sure if there is
> anything else I can try,  I'm looking around for some other machines
> with older cygwins on them to establish what version it stopped working
> in.

Lots and lots of changes has been made between 1.5.5 and 1.5.20.  I don't
recall what was different in relation to process handling, especially
because that's cgf's domain, not mine.

But I can tell you that the above perl script is missing a crucial
point.  The parent doesn't reap its children using wait.  As a result,
the parent has references to its children which just add up, since it
gets no chance to drop the references.

For quite some time each Cygwin process has a maximum number of 256
active children.  If a child exits,  the parent still has to keep the
references in its table, since otherwise it would lose the information
it has to return to the user code when/if the user code calls wait.
Only if the parent calls wait or waitpid, the child entry is removed
from the list and there's room for another new child process.  When this
static list of child processes is full, fork fails.

So, what your application just has to do is to keep the number of active
children below 256.  For instance, if you change your code to:

	  foreach my $incr (`seq 1 1 800`) {
                    unless (defined ($pid = fork)) {
                         die " cannot fork $!";
                     }
                    unless ($pid) {
                      print " the sequence is $incr \n";
                      exit;
                    } else {
		      my $reap_pid;
		      $reap_pid = wait
		    }
             print "pid is $pid\n";
           }

it runs to the end successfully.


Corinna


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]