You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Chris Thorman <ct...@webfeeds.com> on 2000/02/14 21:24:58 UTC

Can file-scoped "my" variables be shared by child processes?

Hi,

The mod_perl website tells us that modules can pre-define package global variables at server startup time and have the data be shared by child processes:

http://perl.apache.org/guide/porting.html#Sharing_variables_between_proces

>*	Global variables initialized at the server startup, through 
>the Perl startup file, can be shared between processes, until 
>modified by some of the processes. e.g. when you write:
>   $My::debug = 1;
>
>all processes will read the same value. If one of the processes 
>changes that value to 0, it will still be equal to 1 for any other 
>process, but not for the one which actually made the change. When a 
>process modifies a shared variable, it becomes the process' private 
>copy.

Is the same true for file-scoped "my" variables?

I'd like to create an object that stores some big read-only data in a file-scoped "my" variable:

package ThisObject;

my $BigPrivateReadOnlyData;
BEGIN
{
    $BigPrivateReadOnlyData = `cat somebigfile.txt`; ## for example.
}

sub MyMethod
{
    my $this = shift;
    my $DataCopy = $BigPrivateReadOnlyData;

    # etc.
}

My guess is that "my $Big..." should work just as well as "$My::Big...".

Does it?

--------

ANOTHER QUESTION ABOUT SHARED VARIABLES:

What happens if I do pattern-matching that might modify the pos() of a scalar that's been shared?

For example:

 my $FoodCount = ($BigPrivateReadOnlyData =~ m/dog: (food)/g);

Does modifying the pos() of a shared variable make the variable unshared?

--------

Thanks in advance to the person who knows the answer to these imponderables.

-chris

------------------------------------------------------------------------
870 Market Street #1270                           (415) 394-9818
San Francisco, CA 94102                           (413) 473-0853 fax
------------------------------------------------------------------------

Re: Modifying the pos() of a shared variable...

Posted by Chris Thorman <ct...@webfeeds.com>.
Cool!  Amazing to see that it's OK to modify the pos without unsharing the string, also that read-only lexicals are properly shared.

Stas, thanks for this brilliant example.

-c

>> >> Does modifying the pos() of a shared variable make the variable unshared?

---------
Here is the example of how to test your considerations:

Shared.pm (preloaded at the server startup)
---------
package Shared;
use Apache::Peek;
my $lexical = "Chris";
sub match{      $lexical =~ /\w/g;                  }
sub print_pos{  print "pos: ", pos($lexical), "\n"; }
sub dump {      Dump($lexical);                     }
1;
--------

test.pl
-------
use Shared;
print "Content-type: text/plain\n\n";
print "PID: $$\n";
Shared::match();
Shared::print_pos();
Shared::dump();
--------------

Set :
	MaxClients 2
for easier tracking.

after several execution, where pos() returns different values for the 2
processes we see:

PID: 27040
pos: 1
SV = PVMG(0x853db20) at 0x8250e8c
  REFCNT = 3
  FLAGS = (PADBUSY,PADMY,SMG,POK,pPOK)
  IV = 0
  NV = 0
  PV = 0x8271af0 "Chris"\0
  CUR = 5
  LEN = 6
  MAGIC = 0x853dd80
    MG_VIRTUAL = &vtbl_mglob
    MG_TYPE = 'g'
    MG_LEN = 1

PID: 27041
pos: 2
SV = PVMG(0x853db20) at 0x8250e8c
  REFCNT = 3
  FLAGS = (PADBUSY,PADMY,SMG,POK,pPOK)
  IV = 0
  NV = 0
  PV = 0x8271af0 "Chris"\0
  CUR = 5
  LEN = 6
  MAGIC = 0x853dd80
    MG_VIRTUAL = &vtbl_mglob
    MG_TYPE = 'g'
    MG_LEN = 2

All the addresses are the same, therefore the variable is still shared. 
The only difference is in SV.MAGIC.MG_LEN, which is not shared. I don't
know how properly to call the state of the variable, but at large it's
non-shared, while the biggest part of it is shared. 
---------


------------------------------------------------------------------------
870 Market Street #1270                           (415) 394-9818
San Francisco, CA 94102                           (413) 473-0853 fax
------------------------------------------------------------------------

Re: Can file-scoped "my" variables be shared by child processes?

Posted by Stas Bekman <sb...@iname.com>.
> >> My guess is that the value of [a file-scoped "my" variable whose
> value is set only once in a BEGIN{} block] should [be shared by child
> processes] just as well as a global.  

> >Hmm, why not to try before asking? It takes exactly 1 minute.  It
> doesn't work. Please read about variable scoping in the perl books and
> >other docs.
> 
> ==> This was not a newbie question about scoping. In fact, it does seem
> to work just fine.  Maybe it's not getting shared.  Will test to see if
> BEGIN block is re-executing in child processes.  BEGIN blocks are
> supposed to execute at compile time.  Since there's only one compile
> time (in the parent process), it seems like the "my" variables are
> getting shared. But frankly, the question is not DOES it work (in
> whatever build I happen to be using) so much as, what's it SUPPOSED to
> do, in theory, and why.  The scope of the variables is obvious.  It's
> the sharedness that I am questioning. 

> >> Does modifying the pos() of a shared variable make the variable unshared?
> >
> >this is an offtopic question -- please use the appropriate forum for this
> >kind of questions. e.g. news:comp.lang.perl.misc 
> 
> ==> What?  Variables shared between parent/children Perl processes is a
> situation that arises uniquely in a modperl context, as far as I can
> tell -- it would be off-topic on a general perl list.  In any case, the
> fact that it's something a modperl user could benefit from knowing when
> writing code for modperl seems to be justification alone for asking it
> here.  So the question stands. 

Please accept my apology, you are very on-topic :)

Here is the example of how to test your considerations:

Shared.pm (preloaded at the server startup)
---------
package Shared;
use Apache::Peek;
my $lexical = "Chris";
sub match{      $lexical =~ /\w/g;                  }
sub print_pos{  print "pos: ", pos($lexical), "\n"; }
sub dump {      Dump($lexical);                     }
1;
--------

test.pl
-------
use Shared;
print "Content-type: text/plain\n\n";
print "PID: $$\n";
Shared::match();
Shared::print_pos();
Shared::dump();
--------------

Set :
	MaxClients 2
for easier tracking.

after several execution, where pos() returns different values for the 2
processes we see:

PID: 27040
pos: 1
SV = PVMG(0x853db20) at 0x8250e8c
  REFCNT = 3
  FLAGS = (PADBUSY,PADMY,SMG,POK,pPOK)
  IV = 0
  NV = 0
  PV = 0x8271af0 "Chris"\0
  CUR = 5
  LEN = 6
  MAGIC = 0x853dd80
    MG_VIRTUAL = &vtbl_mglob
    MG_TYPE = 'g'
    MG_LEN = 1

PID: 27041
pos: 2
SV = PVMG(0x853db20) at 0x8250e8c
  REFCNT = 3
  FLAGS = (PADBUSY,PADMY,SMG,POK,pPOK)
  IV = 0
  NV = 0
  PV = 0x8271af0 "Chris"\0
  CUR = 5
  LEN = 6
  MAGIC = 0x853dd80
    MG_VIRTUAL = &vtbl_mglob
    MG_TYPE = 'g'
    MG_LEN = 2

All the addresses are the same, therefore the variable is still shared. 
The only difference is in SV.MAGIC.MG_LEN, which is not shared. I don't
know how properly to call the state of the variable, but at large it's
non-shared, while the biggest part of it is shared. 

Regarding the my() scoped variable, I meant that you cannot access it
outside the package, of course it can be shared like a global variable if
you use package's internal subs to access it. And using the above example
you can test your variables for being shared.


_______________________________________________________________________
Stas Bekman    mailto:sbekman@iname.com      http://www.stason.org/stas
Perl,CGI,Apache,Linux,Web,Java,PC     http://www.stason.org/stas/TULARC
perl.apache.org    modperl.sourcegarden.org   perlmonth.com    perl.org
single o-> + single o-+ = singlesheaven    http://www.singlesheaven.com


Re: Can file-scoped "my" variables be shared by child processes?

Posted by "G.W. Haywood" <ge...@jubileegroup.co.uk>.
Hi there,

On Sun, 20 Feb 2000, Chris Thorman wrote:

> This was not a newbie question about scoping.
> It's the sharedness that I am questioning.

At the evident risk of taking some flack here:), have you considered
Doing It Another Way?  There are several ways to achieve the objective
of sharing information between processes.  I don't think I'd want to
spend much time forcing lexically scoped variables to be one of them
because of the trouble with sharing them in nested subroutines that
arises so commonly; occasionally unexpectedly; and if you're careless,
silently.  That topic is well covered in the Guide.  It's just going
to give you trouble later - a maintenance nightmare in a large system.

There was for example a thread on Feb 19 and 20 on exactly the right
topic, "Announce: File::Cache 0.04".  Gunther Birznieks' analysis on
Feb 20 is well worth reading.

Hope this helps,

73,
Ged.



Re: Can file-scoped "my" variables be shared by child processes?

Posted by Chris Thorman <ct...@webfeeds.com>.
Hi Stas,  

Thanks for taking the time to answer...

>> My guess is that the value of [a file-scoped "my" variable whose value is set only once in a BEGIN{} block] should [be shared by child processes] just as well as a global.
>
>Hmm, why not to try before asking? It takes exactly 1 minute.
>It doesn't work. Please read about variable scoping in the perl books and
>other docs.

==> This was not a newbie question about scoping. In fact, it does seem to work just fine.  Maybe it's not getting shared.  Will test to see if BEGIN block is re-executing in child processes.  BEGIN blocks are supposed to execute at compile time.  Since there's only one compile time (in the parent process), it seems like the "my" variables are getting shared. But frankly, the question is not DOES it work (in whatever build I happen to be using) so much as, what's it SUPPOSED to do, in theory, and why.  The scope of the variables is obvious.  It's the sharedness that I am questioning.

>> Does modifying the pos() of a shared variable make the variable unshared?
>
>this is an offtopic question -- please use the appropriate forum for this
>kind of questions. e.g. news:comp.lang.perl.misc 

==> What?  Variables shared between parent/children Perl processes is a situation that arises uniquely in a modperl context, as far as I can tell -- it would be off-topic on a general perl list.  In any case, the fact that it's something a modperl user could benefit from knowing when writing code for modperl seems to be justification alone for asking it here.  So the question stands.

-c

------------------------------------------------------------------------
870 Market Street #1270                           (415) 394-9818
San Francisco, CA 94102                           (413) 473-0853 fax
------------------------------------------------------------------------

Re: Can file-scoped "my" variables be shared by child processes?

Posted by Stas Bekman <sb...@iname.com>.
> The mod_perl website tells us that modules can pre-define package global variables at server startup time and have the data be shared by child processes:
> 
> http://perl.apache.org/guide/porting.html#Sharing_variables_between_proces
> 
> >*	Global variables initialized at the server startup, through 
> >the Perl startup file, can be shared between processes, until 
> >modified by some of the processes. e.g. when you write:
> >   $My::debug = 1;
> >
> >all processes will read the same value. If one of the processes 
> >changes that value to 0, it will still be equal to 1 for any other 
> >process, but not for the one which actually made the change. When a 
> >process modifies a shared variable, it becomes the process' private 
> >copy.
> 
> Is the same true for file-scoped "my" variables?
> 
> I'd like to create an object that stores some big read-only data in a file-scoped "my" variable:
> 
> package ThisObject;
> 
> my $BigPrivateReadOnlyData;
> BEGIN
> {
>     $BigPrivateReadOnlyData = `cat somebigfile.txt`; ## for example.
> }
> 
> sub MyMethod
> {
>     my $this = shift;
>     my $DataCopy = $BigPrivateReadOnlyData;
> 
>     # etc.
> }
> 
> My guess is that "my $Big..." should work just as well as "$My::Big...".
> 
> Does it?

Hmm, why not to try before asking? It takes exactly 1 minute.

It doesn't work. Please read about variable scoping in the perl books and
other docs.

> --------
> 
> ANOTHER QUESTION ABOUT SHARED VARIABLES:
> 
> What happens if I do pattern-matching that might modify the pos() of a
> scalar that's been shared? 
> 
> For example:
> 
>  my $FoodCount = ($BigPrivateReadOnlyData =~ m/dog: (food)/g);
> 
> Does modifying the pos() of a shared variable make the variable unshared?

this is an offtopic question -- please use the appropriate forum for this
kind of questions. e.g. news:comp.lang.perl.misc 


_______________________________________________________________________
Stas Bekman    mailto:sbekman@iname.com      http://www.stason.org/stas
Perl,CGI,Apache,Linux,Web,Java,PC     http://www.stason.org/stas/TULARC
perl.apache.org    modperl.sourcegarden.org   perlmonth.com    perl.org
single o-> + single o-+ = singlesheaven    http://www.singlesheaven.com