preston has asked for the wisdom of the Perl Monks concerning the following question:

I'm having a hard time storing objects in a Thread::Queue. According to the Thread::Queue documentation (BUGS section), '"bless" is not supported on shared references', so let's not go there for now and just talk about sharing ordinary references in a Thread::Queue.

As I understand it, reference sharing is _supposed_ to work fine as long as all the referants are shared in a recursive manner. (Also, threads::shared says references must be shared using &share({}) syntax. Fine..whatever.) When my references are dequeued in another thread, however, the referants appear to be empty. It appears empty regardless of how I go about sharing the entire structure. The attached code illustrates this behavior.

Also , to work around the no-shared-blessed-references problem, I can just re-bless dequeued references as long as I can assume they were all of a certain type whey they were enqueued, right?

Perl 5.8.0 (ithreads) on Red Hat 9. Help!!!! Many thanks in advance,

Preston

#!/usr/bin/perl -wall use strict; #=-=-=-=- require Exporter; package Foo; our @ISA = qw(Exporter); use threads; use threads::shared; use Thread::Queue; sub new { my $class = shift; my $self = {key1 => 'value1', key2 => 'value2'}; share($self); bless($self, $class); return $self; } #=-=-=-=- package Bar; use threads; use threads::shared; use Thread::Queue; my $q = new Thread::Queue; my $thr = threads->new(\&monitorQueue); # Add a reference to an empty hash. my $hash_ref_0 = {}; print "\$hash_ref_0 is a " . ref($hash_ref_0); &share($hash_ref_0); $q->enqueue($hash_ref_0); # Add a reference to a hash with something in it. my $hash_ref_1 = {keyM => "valueM", keyN => "valueN"}; print "\$hash_ref_1 is a " . ref($hash_ref_1); &share($hash_ref_1); # Try sharing the reference. share(%$hash_ref_1); # Try sharing the referant. share($hash_ref_1->{$_}) foreach(keys %$hash_ref_1); # Try sharing all + elements of the referant. $q->enqueue($hash_ref_1); # Add a blessed reference to a hash with something in it. my $hash_ref_2 = new Foo(); print "\$hash_ref_2 is a " . ref($hash_ref_2); &share($hash_ref_2); $q->enqueue($hash_ref_2); $thr->join; sub monitorQueue { while (my $elem = $q->dequeue) { print "Removed $elem from queue"; printHashRef($elem); } } sub printHashRef { my $rhash = shift; print "Key: '$_'\t\tValue: '$rhash->{$_}'" foreach(sort keys %$rhash +); }

Edited by BazB: added readmore tag.

Replies are listed 'Best First'.
Re: Sharing (blessed)? references with Thread::Queue.
by liz (Monsignor) on Jan 07, 2004 at 17:45 UTC
      Liz,

      Thanks a ton for the references! (I assume you are the author of said modules?)

      I think Thread::Queue::Any is what I am looking for, so I'll try that. Is it fair to say that an ordinary Thread::Queue is not capable of doing what I want it to?

      Preston

        Thanks a ton for the references! (I assume you are the author of said modules?)

        Eh... yes, I think so... ;-)

        I think Thread::Queue::Any is what I am looking for, so I'll try that. Is it fair to say that an ordinary Thread::Queue is not capable of doing what I want it to?

        I'm not 100% sure that Thread::Queue::Any can do what you want. Even though you can pass references to Thread::Queue::Ant, you are in fact copying the structure that lies behind the reference. So any change you make in one thread will not seen in the other threads. I couldn't make out from your example whether that is what you wanted or not.

        Liz