in reply to ithreads, shared variables..

...You cant share a blessed object though, since whenever you share something, its contents get clobbered...

Actually, sharing a simple scalar does keep its value:

use threads; use threads::shared; my $foo = "foo\n"; share( $foo ); print $foo; __END__ foo

Internally, share() is basically a tie on the reference of what is specified. This is the same approach I use with forks: oddly enough, forks doesn't have that problem, e.g. with a hash:

use forks; use forks::shared; my %foo = (bar => "foo\n"); share( %foo ); print %foo; __END barfoo
I think I'll keep this "inconsistency" in forks, but will add a little note in the pod about this. I agree this is a bug in threads::shared that should be fixed. As always, patches are welcome ;-)

...These and other things might have been useful to put the threads::shared docs...

Please feel free to supply a documentation patch to p5p, or a proposal for (additional) text here (in which case I'll turn it into a documentation patch and submit it to p5p on your behalf).

...it seems I can cheat a little, use freeze/thaw, and actually share objects...

FWIW, that's the approach that Thread::Queue::Any, Thread::Conveyor and Thread::Tie use under the hood (which is actually externalized into its own module: Thread::Serialize).

...Anyone know how, what, why and WTF?

Look at shared.xs in your Perl distribution. I think most of the problem comes from the fact that there is internally only 1 subclass for the tieing: threads::shared::tie. Whereas in forks, I have taken the approach of creating a seperate subclass for each data type.

Hope this helps.

Liz

Replies are listed 'Best First'.
Re: Re: ithreads, shared variables..
by castaway (Parson) on Dec 26, 2003 at 09:36 UTC
    Ok.. I missed the fact that simple scalars actually keep their values when shared.. That does indeed look like a bug then, it's inconsistent.

    My suggestion for the docs would be manyfold. First, they should probably mention that shared variables are implemented using 'tie'. Second, that sharing already filled complex vars (arrays, hashes) clobbers the contents. While we're at it, the Thread::Queue documentation could mention that 'elements' in its case are just simple scalars, and not references to arrays etc. (It just mentions 'scalars' which can contain any number of things).

    So for threads::shared:
    NOTES

    sharing is implemented via tied variables, and thus all caveats applying to those should be applied here too.
    BUGS
    "bless" is not supported on shared references. In the current version, "bless" will bless the reference in each thread, but the objects in each will work independantly. This is expected to be implemented in a future version of Perl.
    sharing hashes and arrays (and refernces to such) which already contain values is not currently supported, the contents of the hash or array will be deleted. (ie what gets shared is a new, empty structure).
    structures containing code references or globs cannot be put in a shared variable.

    And for Thread::Queue:
    NOTE

    Only simple scalars can be used in Queues, complex scalars such as references and objects cannot be used.

    I've been playing around some more, and having removed code refs from my objects (and replaced with symbolic references, Muhahahaha.. ), I've gotten them shared and usable, even without using freeze/thaw. There was a bug due to a shared variable not having enough scope, which is probably also a sharing/threads bug, it was a closed variable, the functions that used it were inside the correct scope...

    On another note, I have another nit to pick with shared variables (I think you mentioned this recently somewhere..), just sharing a structure (HoH in this case) isnt enough, every single value added to it needs to be shared (if briefly) as well. This is very annoying, it would be nice to be able to specify that the thing being added is being added by value, if that makes any sense. Thus:

    my $HoH : shared = {}; sub add_thing { my $time = get_time(); $HoH->{'one'} = &share($time); }
    wouldnt need the extra '&share' in the middle there.. silly really, as $time is about to go back out of scope.

    No doubt this also makes more sense if I read the source.. I'll take a look, but I'd prefer to be able to treat such things as black boxes, and have the documentation explain what they do, without taking them apart myself.

    Update: Oops, blessing propagates, but doesnt actually work.. darn it!

    C.