section "Errors and limitations" in threads :: general documentation warns
When share used for arrays, hashes, arrays, or hash links, any data they contain will be lost.
[...]
Thus, write down such variables after , declaring them as general. (Scalar and scalar links are not affected by this issue.)
You lose data in newly created objects and set later warnings without initialization with
for (0..2) { my $o = obj->new(); $o->setData($_); push @objs, share($o);
Note the other warning in the documentation on topics :: shared.
It is often unreasonable to share an object if the class itself has not been written to support sharing. For example, an object destructor may be called several times, once for each thread visibility thread. Another danger is that the contents of the hash-based objects will be lost due to the aforementioned restriction. See examples/class.pl (in the CPAN distribution of this module) for how to create a class that supports object sharing.
The code in obj.pm becomes
package obj; use strict; use threads; use threads::shared; use warnings; sub new { my $class=shift; share(my %this); $this{"data"} = (); bless(\%this,$class); return(\%this); } sub getData { my $this=shift; lock($this); return $this->{"data"}; } sub setData { my $this=shift; lock($this); $this->{"data"}=shift; } 1;
Changes
- Use streams and streams :: general modules.
- Remove unused exporter spells.
- In the constructor, create an empty shared hash, and then initialize and bless.
- Add
lock calls to accessors.
If you forget to delete the call to share in the loop, you will still receive all warnings. Change the loop to
foreach (0..2){ my $o = obj->new(); $o->setData($_); push @objs, $o;
to get the following conclusion.
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2