h3xx wrote:
> I wrote a module that was designed to be instantiated and that object
> be used by multiple threads. I guess I didn't exactly plan this out
> from the beginning and ran into problems when trying to set it up so
> that there was only one copy of the object and its data structure in
> memory, while multiple threads called its subs.
>
> Seeing as I couldn't just create an object in memory and share a
> REFERENCE to it (this was my original plan, but that's apparently not
> how threading works), I set about making it so the class, when
> instantiated, existed in shared memory. I'm using threads::shared, by
> the way.
>
> My problem is that creating the object in the new() subroutine is
> tedious, making sure every single bit of the data structure (most of
> which is passed in as arguments) is &share()d. This gets especially
> tiresome when the user passes a multi-dimensional hash reference as a
> constructor argument.
>
> My question is whether there is a simpler way for creating an packaged-
> based blessed object so that it and ALL its data structures exist in
> shared memory?
>
> Sample package with constructor:
>
> package Foo;
>
> sub new {
> my $class = shift;
> bless {
> 'option1' => 80,
> 'mydata' => {},
> # over-ride with passed-in named arguments
> @_,
> }, $class
> }
>
> __END__
>
> Called with:
>
> my $f = Foo->new(
> 'option1' => 20,
> 'mydata' => {
> [ "one", "two" ],
> [ "three", "four" ],
> }
> );
>
> __END__
>
> I tried it with "bless &share({ ... }), $class" but that returns an
> empty blessed object.
Any data in a hash will be cleared out when you share() it, so you need to
populate it after the share - something like
sub new {
my $class = shift;
my $self = &share({});
%{$self} = (
option1 => 80,
data => &share({}),
@_,
);
# Populate $self->{data} etc.
bless $self, $class;
}
(Note that the ugly &share() call is necessary only when sharing anonymous data
structures.)
But each of the nested data structures must be shared individually, so you can't
just copy them in from the constructor parameters.
Will your object be modified after it is initialized? If so there is no need to
share it at all as long as the threads are created after the object - each
thread will have its own identical copy of the data and should work fine.
Otherwise as far as I can see you have two choices: redesign your solution, or
write a recursive data clone function that will share each substructure before
it is populated.
I hope this helps a little.
Rob
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/