Sharing object between threads - howto?

Sharing object between threads - howto?

am 08.09.2007 13:47:14 von Lejf Diecks

Hi,

is it possible to share an object between the main program and a thread?

I wrote a class "SuperSnoop.pm" with the following constructor:

-- ---
package PlugIn::SuperSnoop;

sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
return $self;
}
-- ---

In the main program I create a new "SuperSnoop"-object and pass it to a
thread:

-- ---
use threads;

sub startThread {
my ($obj) = @_;
print "Object inside thread: $obj\n";
}

my $obj = SuperSnoop->new();
print "Object outside thread (1): $obj\n";
my $thr = threads->create("startThread", $obj);
print "Object outside thread (2): $obj\n";
-- ---

Problem: It seems to me that "threads" creates a copy (!) of the object,
because the reference changes INSIDE the thread:

-- ---
Object outside thread (1): PlugIn::SuperSnoop=HASH(0x10413d4c)
Object inside thread: PlugIn::SuperSnoop=HASH(0x106ea164)
Object outside thread (2): PlugIn::SuperSnoop=HASH(0x10413d4c)
-- ---

I tried "threads::shared" from CPAN, but it does'nt work for me. The
perldoc for "threads::shared" points out:

"BUGS: bless is not supported on shared references. In the current
version, bless will only bless the thread local reference and the
blessing will not propagate to the other threads. This is expected to be
implemented in a future version of Perl."

Is there a way to get it work anyway? I need only one instance of each
object at runtime.

Regards,
Lejf

Re: Sharing object between threads - howto?

am 10.09.2007 14:19:49 von zentara

On Sat, 08 Sep 2007 13:47:14 +0200, Lejf Diecks
wrote:

>Hi,
>
>is it possible to share an object between the main program and a thread?

See:
http://perlmonks.org?node_id=637089

It's uncharted territory, and you might run into portability problems
even if you get it to work on your machine.

zentara

--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html

Re: Sharing object between threads - howto?

am 11.09.2007 21:00:19 von Mike Pomraning

Lejf Diecks wrote:

> is it possible to share an object between the main program and a thread?

Yes, easily. Thread::Queue, for example, does this:

sub new {
my $class = shift;
my @q : shared = @_;
return bless \@q, $class;
}

> I tried "threads::shared" from CPAN, but it does'nt work for me.

Your examples didn't show any sharing, either with the :shared attribute
or threads::shared::share().

> The perldoc for "threads::shared" points out:
>
> "BUGS: bless is not supported on shared references. In the current
> version, bless will only bless the thread local reference and the
> blessing will not propagate to the other threads. This is expected to be
> implemented in a future version of Perl."

This disclaimer is unfortunately phrased and easy to misread/mislead.

Briefly, perl thread creation clones (copies) all variables for the new
thread. Subsequent clones of blessed objects are themselves blessed
(barring something like CLONE_SKIP). Subsequent clones of shared
objects are magically tied together so that they refer to the same
underlying variable and can be safely manipulated (lock()d,
cond_signal()d, etc.).

Subsequent clones of blessed, shared objects are both blessed and
magically tied together. However, blessing a shared object does not
update _already existing_ clones tied to that shared object, as it very
plausibly should. That is the bug.

Note that this bug is never an issue if you bless/share while only only
one thread is aware of the object, for example in your class' constructor.

Regards,
Mike

Re: Sharing object between threads - howto?

am 20.09.2007 11:59:26 von ldiecks

On 11 Sep., 21:00, Mike Pomraning
wrote:
> Yes, easily. Thread::Queue, for example, does this:
>
> sub new {
> my $class = shift;
> my @q : shared = @_;
> return bless \@q, $class;
> }

Hello Mike,

thank you for your detailed answer (constructor)! Using Thread::Queue
I was able to solve the problem. This saved me from many sleepless
nights :-)

Regards,
Lejf