Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Like other responses, I'm confused by your description of what you are trying to do. You say:

Why would I want to do this, people ask? Well, I can't add un-shareable values to shared hashes (objects), which I, sadly, need to do.

But that seems to be the exact opposite of what you are asking for? Ie. You say you can't copy unshareable values into a shared hash, but you're asking how to 'unshare' shared data?

To answer the question you've asked--how to unshare, shared data--delete it. Once it is deleted by one thread, no thread can access it.

If you need one thread to continue to have access, duplicate it (Clone would work) into a thread local, none shared copy, and then (deep) delete the shared copy. You might need something like (Rmap or Data::Diver to ensure that if another thread has taken a reference to some subset of the original data structure (I'm assuming this is what you meant by "blob"), that it will no longer have access to the data. Of course, if it has already taken a copy (shared or otherwise), you will not be able to prevent it from continuing to access the copy!

But, I suspect, that that isn't what you meant to ask. My suspicion is that you have a non-shared, complex, data-structure, and what you want to do is transfer a copy of to another thread. And you are falling foul of the threads::shared::share() inability to share nested data structures?

If this is the case, then you need to traverse the data structure manually and share then copy nested elements individually and recursively. You might find this (lightly tested and unpublished...it still has limitations) module useful:

{ package shareDeep; ## threads::shareDeep is the intended name for +release... use strict; use warnings; use threads; use threads::shared qw[ bless ]; use Carp qw[cluck carp]; use Scalar::Util qw[ readonly reftype blessed ]; require Exporter; our @ISA = 'Exporter'; our @EXPORT = qw[ shareDeep ]; our $TRACE = 0; *_trace = $TRACE ? sub{ my $fmt = shift; warn( sprintf "%3d %s(%d): %s\n", threads->self->tid || 0, __FILE__, __LINE__, $fmt, @_ ); } : sub(){ 0 }; sub _invalid { warn( "Can't share '$_[ 0 ]'; substituting as placeholder\ +n", ); return "$_[ 0 ]"; } sub getType { blessed( $_[ 0 ] ) ? reftype( $_[ 0 ] ) : ref( $_[ 0 + ] ); } my %do; %do = ( '' => sub { _trace( "VALUE: @_ : " . getType( $_[ 0 ] ) ); $_[ 0 ] }, SCALAR => sub { _trace( "SCALAR: @_ : " . getType( $_[ 0 ] ) ); my $scalar :shared = ${ $_[ 0 ] }; \$scalar }, HASH => sub { _trace( "HASH: @_ : " . getType( $_[ 0 ] ) ); my $in = shift; my %hash :shared = map { $_ => $do{ getType( $in->{ $_ } ) }->( $in->{ $_ } ) } keys %{ $in }; \%hash; }, ARRAY => sub { _trace( "ARRAY: @_ : " . getType( $_[ 0 ] ) ); my @array :shared = map{ $do{ getType( $_ ) }->( $_ ) } @{ $_[ 0 ] }; \@array; }, REF => sub { _trace( "REF: @_ : " . getType( $_[ 0 ] ) ); my $ref :shared = $do{ getType( ${ $_[ 0 ] } ) }->( ${ $_[ + 0 ] } ); \$ref }, GLOB => \&_invalid, LVALUE => \&_invalid, CODE => \&_invalid, Regexp => \&_invalid, ); readonly( \%do ); sub shareDeep { my( $in ) = shift; return my $out :shared = $do{ getType( $in) }->( $in ); } } return 1 if caller; package main; use threads; use threads::shared qw[ bless ]; use Data::Dump qw[ pp ]; $Data::Dump::MAX_WIDTH = 500; shareDeep->import; sub test{ print "test sub @_" }; my %test = 1 .. 10; my $rSharedHash = shareDeep( \%test ); pp $rSharedHash; my @test = 1 .. 10; my $rSharedArray = shareDeep( \@test ); pp $rSharedArray; my $test = 'test'; my $rSharedScalar = shareDeep( \$test ); pp $rSharedScalar; my $rSharedRef = shareDeep( \\$test ); pp $rSharedRef; $rSharedRef = shareDeep( \\\\\\\\\\$test ); pp $rSharedRef; my $lvalue = \substr( 'fred', 1, 2 ); my $sharedLvalue :shared = shareDeep( $lvalue ); pp $sharedLvalue; my $glob = do{ local *GLOB; \*GLOB }; my $sharedGlob :shared = shareDeep( $glob ); pp $sharedGlob; my %hash = ( array => \@test, hash => \%test, ); my $nested :shared = shareDeep( \%hash ); pp $nested; my $blessed :shared = shareDeep( threads::shared::bless [], 'fred' ); print pp $blessed;

It exports a single entrypoint, shareDeep() that will return (by reference) a fully shared duplicate of the structure passed in. (Also by reference.)

It currently issues a warning for any unshareable elements contained in the structure to be copied, and substitutes a placeholder. Probably not the best design choice, but useful while I decide if there is a better approach.

The embedded tests should serve as a guide to usage.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

In reply to Re: How can I unshare something? by BrowserUk
in thread How can I unshare something? by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-19 23:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found