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

Hi,
I have a working model where a main program starts threads
that dynamically load another named program.
It is like a plug-in style system.
I run it under Windows 2000, Activestate 5.8.
Now, I want multiple instances of the same loaded program
to share common resources. In my example I want a global static $q to be
accessed by the second invocation of "xy1".

1) How shall I do it if I place this resource in the main file?
2) How do I place this resource just in the loaded file (preferred)?
If this model can be inproved, please advise.

You can test it; In the stripped-down version below,
cut the code into 2 files, "xy_load.pl" and "xy1.pm",
and place in same directory.
TIA
J. Merc
#================== xy_load.pl ============= #! /usr/bin/perl -w use 5.008; # 5.8 required for stable threading package xy_load; use strict; no strict 'subs'; no strict 'refs'; use warnings; use threads; use File::Basename; my $HOME = dirname($0); # directory the program loaded from push(@INC, $HOME); # Set in perl's include path list $| = 1; my $p = 0; # counter my $sub = "xy1"; # the name of program to load my $thr1 = threads->create(\&start_thread, $sub, $p ); $p++; my $thr2 = threads->create(\&start_thread, $sub, $p ); $thr1->join; $thr2->join; sub start_thread { my ($sub, $p )= @_; eval "require $sub"; # load the passed program &{"xy_load::" . $sub . "::Process"}($p); # and run it } #================ xy1.pm ============ package xy_load::xy1; ### I want $q as shared global to all invocations of "xy1", my $q : shared = 0; sub Process { my $p = $_[0]; my $tid = threads->self->tid; $| = 1; { lock ($q); $q++; print STDERR "TID: $tid, p = $p, q = $q\n"; } } 1; # success status for require

Replies are listed 'Best First'.
Re: Threads, dynamic loading programs, and using globals?
by pg (Canon) on Jan 04, 2003 at 21:20 UTC
    First I have to agree that, your way of using thread and package is quite creative, and to be frank, I like the thinking. But perl does have a little problem with this.

    The main problem is that. The shared variable can only be shared within one invocation of the package, or we can say that, that shared variable has a per package scope.

    If you have two invocations of a package. Each of them will have its own instance of that shared variable, not a SINGLE one as you expected. (I have to say that Perl does this perfectly, and this is how it should be.)

    You may have to redesign the overall structure of your application.

    I attached some pieces of code to test this.
    package ex3.pm: use threads::shared; use strict; my $p; share($p);#a shared variable, and we will see that it has a per invoca +tion scope. sub process1 { while (1) { print "process1 thinks \$p = $p\n";#if it is shared, you will +see the bumps sleep(1); } } sub process2 { while (1) { $p ++; print "process2 bumped \$p to $p\n";#the bump should affect pr +ints from process1, if $p is shared. sleep(1); } } ex3.pl: demo the failure of share between invocations. use threads; use strict; my $th1 = threads->create (sub {require ex3;#invocation 1 process1(); }); my $th2 = threads->create (sub {require ex3;#invocation 2 process2(); }); $th1->join; ex4.pl: demo the succ of share within the same invocation. use threads; use ex3;#once for all use strict; my $th1 = threads->create (sub { process1(); }); my $th2 = threads->create (sub { process2(); }); $th1->join;