in reply to Is a called package in thread storage?

are its local (my) variables in global storage or thread storage?

My first reaction to this is: Why do you want to know?

But since such meta-questions can be really annoying, I'll expand a little :)

Pretty much everything user accessible in Perl is allocated from the process heap. That said, there is a complication in that the heap is broken up into buckets and some buckets can be reserved for use by particular threads.

The important thing about about variables in threaded programs, is not where the storage is allocated. It is their visibility.

A secondary consideration is whether they are cloned, but that's a complex issue that would require a lot of words to describe. And someone intimately familar with Perl's internals to both describe, and subsequently understand the description.

Which brings us back to my initial reaction above. If you explain why you want (or think you need?) to know, then you're more likely to get a reply that will be useful to you.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."
  • Comment on Re: Is a called package in thread storage?

Replies are listed 'Best First'.
Re^2: Is a called package in thread storage?
by Wiggins (Hermit) on Jul 15, 2008 at 20:12 UTC
    What got me started was following multiple threads calling the same MIME decomp code, and preempting each other. I flashed back to the the techniques to do recursion, and the use of the activation record to store all working variables going through the common code on each cycle through. In OO, a new object encapsulates all of the object specific working space (or pointers to heap space).

    Would my package allocate a hash during thread 1(T1), then be preempted by T2, which, finding the hash already there just start stuffing more into it.

    My training goes back to linear shared physical memory space for all processes; not this managed buckets of private pointers to allocated heap space.

    I feel better now... thanks ... I guess I am a hand-on sort of person.

      At the simplest level, all you need to know is that unless you explicitly share a variable, only the thread that declared it can access it. They are invisible to other threads.

      However, there is a caveat. That all variables instantiated before you spawn a thread, are cloned into that thread. Both the spawned thread and the spawning thread will have entirely independent copies of those variables that existed at the point of thread creation. The effect is very similar to the fork mechanism whereby the state of the process is cloned and each process (parent and child) have their own copies of everything that existed at the fork point.

      However, there is a caveat with that description also, in as much as process global resources, like the standard file handles, pre-existing sockets etc. are not entirely independent of each other. This has consequences that you need to be aware of. For example:

      use threads;; open O, '>', 'junk.dat';; ## Open a file print O $_ for 1 .. 100; ## print some stuff to it print tell O;; ## print the file pointer position 392 async{ ## spawn a thread print tell O; ## inherits a (cloned) copy of the file + handle 392 ## complete with pre-existing state print O $_ for 1 .. 100; ## print some more stuff from within th +e thread print tell O; ## And it's copy of the file handle ref +lects the change 784 };; print tell O;; ## but back in the main thread the orig +inal doesn't see it 392 print O $_ for 1 .. 100;; ## even after local modifications print tell O;; ## 784 close O; exit;; c:\test>wc -l junk.dat ## All the output ended up in the file, + 300 junk.dat ## But neither threads file handle ## reflects the true pointer position.

      That's probably the worst anomalous behaviour. It's 'safe' to use file handles from more than one thread, provided you use locking to prevent interspersion of output, but do not rely upon the output from tell.

      Another consequence of the cloning is that if you allocate large data structure before spawning threads, each thread spawned afterward will get a copy of that data structure regardless of whether it needs it or not.

      The trick here is to spawn early and require packages within the threads that need them rather than useing them. With care, you can control (to some degree) what packages are loaded into what threads.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.