X-Spam-Check-By: sourceware.org Date: Wed, 19 Jul 2006 12:08:24 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: Perl failure Message-ID: <20060719100824.GD18664@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <20060713180601 DOT GA3872 AT efn DOT org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2i Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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 AT 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/