in reply to Re^2: Defining global variable in a subroutine
in thread Defining global variable in a subroutine

This also will work in a forked environment, since the global 'our' variable is in the address space of the parent.

Could you elaborate what you mean by that?

Almost sounds like you are saying the child process could modify the variable in the parent process.  If so, I'd like to see a demo.

  • Comment on Re^3: Defining global variable in a subroutine

Replies are listed 'Best First'.
Re^4: Defining global variable in a subroutine
by flexvault (Monsignor) on Feb 22, 2012 at 15:09 UTC

    Eliya,

    If you take a look at Re: Accessing hash from within module, which I commented on how to use/update globals in the parent, I think it gives enough information to explain what I'm talking about.

    Also remember, it you use 'our' in the child, it creates the global in the parent space, and not in the child's address space. That's why you need to LOCK/UNLOCK the global that you are using.

    Good Luck!

    "Well done is better than well said." - Benjamin Franklin

      An 'our' variable (or any normal variable for that matter) is not shared between parent and child after a fork.
      our $x = 1; my $f = fork; die $! unless defined $f; if ($f) { # parent sleep 1; print "parent: x=$x\n"; # prints 1 } else { $x = 2; exit; }

      Dave.

      After having read the linked thread, I'm still not sure what your message is with respect to forking.

      For all practical matters, there's no real differnce between accessing an "our" vs. a "my" variable from within a child process.  In both cases, the child has access to the variable's value as it was at the time of the fork, but as soon as either the child or the parent modifies it, they become different entities stored at different memory locations (due to the copy-on-write mechanism).  In other words, neither the child nor the parent can "update" the variable in the other process.

      #!/usr/bin/perl -wl use strict; our $var = "foo"; # my $var = "foo"; # same thing wrt fork sub modify_var { $var = shift; } unless (fork) { sleep 1; print "child: $var"; modify_var("bar"); print "child: $var"; } else { modify_var("baz"); wait; print "parent: $var"; }

      prints (as expected):

      child: foo child: bar parent: baz

      As I'm reading your comment, you'd expect the output to be (?)

      child: baz child: bar parent: bar

      As you can see, the variable is not shared.

        Eliya,

        I downloaded and tested your script, and it does exactly as you say.

        So I have a production 20,000 line application that does the following:

        Parent process

        • Startup and initialize all "common" hashes (ie %SYS, %Account, ... )
        • Establish socket communication
        • fork children that wait on socket (usually at least 4 children, but in one case their are 128 children)
        • Maintain children

        Child process

        • wait on socket
        • do work when communication received (GET/POST data) from cgi script called from web server and returns html to the cgi script, which returns the html to the server.
        • exit after nn number of calls

        So that's the high level picture. Now the actual work that goes on is all done by subroutine calls from a child as follows:

        • User logs in with account/password.
          • Child verifies account and creates a $Account{user}{ } HoH .
            Note: each user has about 60-100 hash fields. child returns html to caller.
        • user clicks on things they want
          • each click results in call to different children that use the $Account{user}{ HoH } to read/update/delete values. Notice we don't know which child will be working on which user. We use *nix logging so we can see the different children($$) being called by different users.
        • user logs out and child undefines all hashes created for user.

      So based upon you script this shouldn't work, but it does.

      The parent doesn't look at any of the 'our' hashes, only the children and each child logs information that they have used from the global hashes.

      Now I'm confused at a different level.

      Thank you

      "Well done is better than well said." - Benjamin Franklin