perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pawel Herman <busymeis...@gmail.com>
Subject Sharing variable in threaded mpm not working as expected
Date Tue, 02 Aug 2011 07:06:59 GMT
Hello,

I have read all the related documentation (at least those that I
found) and I still cannot understand why the little program I wrote
below does not share the variable as I would expect.  The log file
that I created clearly shows that we are running in a single process.
Some threads see the shared variable and others do not.  I even
reduced the number of pooled interpreters to one and still no luck.

You will need an Apache running in Ubuntu 11.04 with mod_perl 2.0.
Then add this code:

package U2D::TestSharing;

use strict;

use Apache2::Const -compile => qw(OK);
use threads;
use threads::shared;
use APR::OS ();
use Time::Format qw(%time);
use Apache2::RequestRec;

our @fruits :shared = ();

sub handler {
    my $r = shift;
    $r->content_type('application/json');

    {
        logTestMessage('Waiting for lock.');
        lock(@fruits);
        logTestMessage('Acquired lock.');
        if(scalar(@fruits) == 0) {
            logTestMessage('Initializing fruits.');
            push(@fruits,'apple');
            push(@fruits,'banana');
            push(@fruits,'peach');
        }
        logTestMessage('Releasing lock.');
    }

    my $message = "I like to eat ".join(', ',@fruits).".";

    print $message;
    logTestMessage($message);

    return Apache2::Const::OK;
}

sub logTestMessage {
    my $message = shift;
    my $tid = APR::OS::current_thread_id();
    if(open(FILE,'>>/testSharing.log')) {
        print FILE $time{'dd-mm-yyyy hh:mm:ss:mmm'}.' '.$$.'-'.$tid.':
+ '.$message."\n";
        close(FILE);
    } else { print $!."\n"; }
}

1;

Add the following lines to apache2.conf (or uncomment the specified lines):

<IfModule mpm_worker_module>
    StartServers          1
    MinSpareThreads       5
    ThreadsPerChild      20
    MaxRequestsPerChild   0
    ServerLimit           1
    PerlInterpMax         1
</IfModule>

To the site configuration also add:

<Location /testSharing>
    SetHandler perl-script
    PerlResponseHandler U2D::TestSharing
</Location>

Then write a little JavaScript that loops 100 times and calls
http://localhost/testSharing and check the log file. Here I am posting
the beginning of the log on my machine:

02-08-2011 07:42:27:552 2669-3063479152: Waiting for lock.
02-08-2011 07:42:27:565 2669-3063479152: Acquired lock.
02-08-2011 07:42:27:566 2669-3063479152: Initializing fruits.
02-08-2011 07:42:27:566 2669-3063479152: Releasing lock.
02-08-2011 07:42:27:566 2669-3063479152: I like to eat apple, banana, peach.
02-08-2011 07:42:27:578 2669-3063479152: Waiting for lock.
02-08-2011 07:42:27:578 2669-3063479152: Acquired lock.
02-08-2011 07:42:27:578 2669-3063479152: Releasing lock.
02-08-2011 07:42:27:578 2669-3063479152: I like to eat apple, banana, peach.
02-08-2011 07:42:27:578 2669-3021515632: Waiting for lock.
02-08-2011 07:42:27:579 2669-3021515632: Acquired lock.
02-08-2011 07:42:27:579 2669-3021515632: Releasing lock.
02-08-2011 07:42:27:579 2669-3021515632: I like to eat apple, banana, peach.
02-08-2011 07:42:27:574 2669-3046693744: Waiting for lock.
02-08-2011 07:42:27:582 2669-3046693744: Acquired lock.
02-08-2011 07:42:27:582 2669-3046693744: Initializing fruits.
02-08-2011 07:42:27:582 2669-3046693744: Releasing lock.
02-08-2011 07:42:27:582 2669-3046693744: I like to eat apple, banana, peach.
02-08-2011 07:42:27:583 2669-3063479152: Waiting for lock.
02-08-2011 07:42:27:583 2669-3063479152: Acquired lock.
02-08-2011 07:42:27:583 2669-3063479152: Releasing lock.
02-08-2011 07:42:27:583 2669-3063479152: I like to eat apple, banana, peach.
02-08-2011 07:42:27:588 2669-3063479152: Waiting for lock.
02-08-2011 07:42:27:588 2669-3063479152: Acquired lock.
02-08-2011 07:42:27:588 2669-3063479152: Releasing lock.
02-08-2011 07:42:27:588 2669-3063479152: I like to eat apple, banana, peach.
02-08-2011 07:42:27:581 2669-3055086448: Waiting for lock.
02-08-2011 07:42:27:589 2669-3055086448: Acquired lock.
02-08-2011 07:42:27:589 2669-3055086448: Initializing fruits.
02-08-2011 07:42:27:589 2669-3055086448: Releasing lock.
02-08-2011 07:42:27:589 2669-3055086448: I like to eat apple, banana, peach.
02-08-2011 07:42:27:582 2669-3038301040: Waiting for lock.
02-08-2011 07:42:27:589 2669-3038301040: Acquired lock.
02-08-2011 07:42:27:589 2669-3038301040: Initializing fruits.
02-08-2011 07:42:27:589 2669-3038301040: Releasing lock.
02-08-2011 07:42:27:590 2669-3038301040: I like to eat apple, banana, peach.
02-08-2011 07:42:27:588 2669-3013122928: Waiting for lock.
02-08-2011 07:42:27:594 2669-3013122928: Acquired lock.
02-08-2011 07:42:27:594 2669-3013122928: Initializing fruits.
02-08-2011 07:42:27:594 2669-3013122928: Releasing lock.
02-08-2011 07:42:27:594 2669-3013122928: I like to eat apple, banana, peach.

The fruits array is initialized multiple times. This is not expected
since the fruits array is shared and we are always running in the same
process. (Note: Thread 2669-3063479152 populates the array initially.
Then thread 2669-3021515632 uses it but thread 2669-3046693744 creates
the array again.  Just as a side note: as I was testing this, I also
ran into situations where multiple threads acquired the lock
simultaneously.  The expected behavior is that only one thread can
lock at a time.)  Can anyone tell me why this code does not work?

Thank you for your help in advance. I hope someone can shed some light
on this problem that I am having for weeks now.

Sincerely,

Pawel

Mime
View raw message