That said, I would personally advocate avoiding using threads unless you absolutely need to.

Most of my programs include server and other working threads.

Make each shared object keep track of how much it is used. In CLONE, increment the usage of each object that the thread will actually use. In DESTROY, decrement the usage of each object that the thread incremented. The key is that you have to decrement all of the things that you increment.

I tried it out, but it doesn't seem to be working better.

Threads are always a huge complication

Looks like you are right. The code below could work better. But... either Perl crashes or threads don't finish anymore. Very strange.

#!/usr/local/bin/perl use threads; use Time::HiRes qw/usleep/; while( 1 ) { my $class = Class->new(); threads->create( \&thread_sub, $class, 0 ); usleep 200_000; } sub thread_sub { my( $class, $level ) = @_; print "THREAD ", threads->self->tid, ", $level running\n"; threads->create( \&thread_sub, $class, $level + 1 ) unless $level; usleep 400_000; print "THREAD ", threads->self->tid, ", $level finished\n"; threads->self->detach; } 1; package Class; use threads::shared; our %MY_CXT : shared = (); our $CXT_ID : shared = 0; sub new { my $class = shift; my $this = {}; $this->{'shared'} = &share( {} ), $this->{'shared'}{'refcnt'} = 1; $this->{'shared'}{'tid'} = threads->self->tid; $this->{'shared'}{'clone'} = 1; lock( %MY_CXT ); $this->{'id'} = ++ $CXT_ID; $MY_CXT{$this->{'id'}} = $this->{'shared'}; bless $this, $class; } sub CLONE { lock( %MY_CXT ); while( my( $k, $v ) = each %MY_CXT ) { # do not CLONE anymore when it's destroyed in the main thread $v->{'refcnt'} ++ if $v->{'clone'}; print "CLONE: id $k, refcnt $v->{'refcnt'}\n"; } } sub DESTROY { my $this = shift; my $shared = $this->{'shared'}; if( $shared->{'tid'} == threads->self->tid ) { # disable futher CLONEs $shared->{'clone'} = 0; # refcnt must decrement twice ? $shared->{'refcnt'} --; } $shared->{'refcnt'} --; print "DESTROY: id $this->{'id'}, refcnt $shared->{'refcnt'}\n"; if( $shared->{'refcnt'} <= 0 ) { lock( %MY_CXT ); # should not happen warn "already destroyed!!!" unless $MY_CXT{$this->{'id'}}; delete $MY_CXT{$this->{'id'}}; } } 1;

In reply to Re^6: CLONE/DESTROY want work at all?? by spacepille
in thread CLONE/DESTROY want work at all?? by spacepille

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.