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

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.

Replies are listed 'Best First'.
Re^6: Defining global variable in a subroutine
by flexvault (Monsignor) on Feb 23, 2012 at 10:14 UTC

    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

      Where does the parent use any value set in a child?

        choroba ,

        Never. Only children process the global hashes

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

      Parent process ... Startup and initialize all "common" hashes (ie %SYS, %Account, ... )

      How does it initialises these hashes? I guess they are tied hashes, perhaps something created with IPC::Shareable.