Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Test::More and semaphore handles on Windows

by eyepopslikeamosquito (Archbishop)
on Aug 25, 2004 at 03:29 UTC ( [id://385572]=perlquestion: print w/replies, xml ) Need Help??

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

I've started running some large Test::More programs (perl 5.8.4) under Windows and noticed that each ok() appears to consume 14 Windows semaphore handles. The test program below demonstrates.

use strict; use Test::More; my $niter = shift or die "usage: $0 number-of-iterations\n"; plan tests => $niter; ok(1) for 1 .. $niter; print "Look at handle count in Windows Task Manager\n"; print "Then press [RETURN] to exit...\n";<STDIN>;

For example, when I run this program for 10,000 iterations, Windows Task Manager reports there are 140,021 handles being used by the perl process. The sysinternals nthandle utility reports they are mainly semaphore handles.

I suspect the underlying reason for all these semaphore handles is the use of share() in Test::Builder. For example:

# Test to simulate semaphore growth in Test::Builder. # Grows by 4 semaphore handles per iteration. use strict; use threads; use threads::shared; my @Test_Results = (); share(@Test_Results); sub ok { my $result = {}; share($result); push(@Test_Results, $result); } my $niter = shift or die "usage: $0 number-of-iterations\n"; ok(1) for 1 .. $niter; print "Look at handle count in Windows Task Manager\n"; print "Then press [RETURN] to exit...\n";<STDIN>;

This is not a handle leak in that the handles are released when the variable goes out of scope.

I'm wondering if anyone has seen this issue before or can shed some more light on it. Since you should generally try to keep each test program quite small, it's unlikely to prove a practical limitation. However, it may prevent you from writing very large stress tests due to handle starvation.

Replies are listed 'Best First'.
Re: Test::More and semaphore handles on Windows
by chromatic (Archbishop) on Aug 25, 2004 at 05:19 UTC

    Test::Builder keeps around information about each test executed to do its reporting at the end of the test file. This is effectively global data.

    So that Test::Builder can work with tests that use thread (or tests for code that uses thread), it has to make sure that that global data is thread-safe, hence the use of sharing.

    This is only an issue with ithreads, so it only affects Perls of 5.7.x and later.

      As I understand it, the problem related to Test::Builder will affect 5.8 and later because the current version of Test::Builder checks that perl version is greater then 5.008 before it enables this thread safety. From Test::Builder:
      BEGIN { use Config; if( $] >= 5.008 && $Config{useithreads} ) { require threads; require threads::shared; threads::shared->import; } else { *share = sub { 0 }; *lock = sub { 0 }; } }
      Is this correct?

        Yes, that's correct, because Perl 5.7.x switched to a different threading model.

Re: Test::More and semaphore handles on Windows
by blm (Hermit) on Aug 25, 2004 at 04:02 UTC

    I get the same

    On my machine (Windows XP SP1 and ActiveState Perl 5.8.4):

    Your first example:

    100,000 iterations ---> 140,021 handles 10 iterations ---> 161 handles.

    Second example:

    100,000 iterations ---> 400,019 handles 10 iterations ---> 59 handles.

    Maybe this is specific to the core modules with the 5.8 distribution?

    On windows XP with Activestate Perl 5.6.1 the first program only uses 16 handles according to windows task manager. This seems independant of how many iterations are performed up to 100000.

    The second doesn't run as there is no Threads::Shared installed with the default install of Activestate Perl 5.6.1

Re: Test::More and semaphore handles on Windows
by blm (Hermit) on Aug 25, 2004 at 05:44 UTC

    I don't understand something. In

    # Test to simulate semaphore growth in Test::Builder. # Grows by 4 semaphore handles per iteration. use strict; use threads; use threads::shared; my @Test_Results = (); share(@Test_Results); sub ok { my $result = {}; share($result); push(@Test_Results, $result); } my $niter = shift or die "usage: $0 number-of-iterations\n"; ok(1) for 1 .. $niter; print "Look at handle count in Windows Task Manager\n"; print "Then press [RETURN] to exit...\n";<STDIN>;

    As I understand scoping, $result goes out of scope at the end of the call to ok() so why doesn't the handles get released then? Instead the handles don't seem to be released until perl.exe is finished. I guess this is to do with threads and making sure all shared data is available to all threads.

      No, $result does not get destroyed then because it has been inserted into @Test_Results (which is still in scope) -- perl's reference counting keeps track of this. Running the following program with a large number of iterations, you'll see the handle count go up and up, then it drops back to the original value at the end of the program (when @Test_Results has gone out of scope).

      use strict; use threads; use threads::shared; sub test { my $niter = shift; my @Test_Results = (); share(@Test_Results); for (1 .. $niter) { my $result = {}; share($result); push(@Test_Results, $result); } } my $niter = shift or die "usage: $0 number-of-iterations\n"; test($niter); print "Look at handle count in Windows Task Manager\n"; print "Then press [RETURN] to exit...\n";<STDIN>;
Re: Test::More and semaphore handles on Windows
by schwern (Scribe) on Dec 01, 2004 at 06:40 UTC

    This has been "fixed" in 0.49. Prior to that Test::More would always load threads.pm and share its internal data if possible to make things thread safe.

    In 0.49 it was changed so Test::More would not load threads.pm for you. You had to do it in your test before loading Test::More. So this bug should no longer effect tests that do not use threads.

    And if you have 10,000 thread-enabled tests, god help you. ;) Actually I've long planned a "no history" option to avoid using too much memory in very long testing situations, so watch for that, too.

    -- Michael G Schwern

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://385572]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (6)
As of 2024-04-19 16:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found