in reply to Re^5: Overriding bless for inside-out object safety
in thread Overriding bless for inside-out object safety

The technique can and should be fairly explored, not dismissed out of hand due to faulty or sub-optimal implementations.

I agree wholeheartedly. I've been quietly following your progress in anticipation of trying out the results.

With respect to the thread safety. I am not convinced is that there is either a need for, or a benefit to, sharing objects between threads. I believe that most everything that can be done by doing so, can also be done, and is (may be) better done through a "messaging" interface.

My opinion is based upon the results of various prototypes I created for a distributed object architecture several years ago. Cooperating objects could variously exist as

We tried various mechanisms, including cross-threaded objects (sic), and on the basis of my experiences then, cross-threaded objects simply ended up getting cross-threaded. Programmed absolutely correctly, they worked reasonably well, but the requirements for the application programmers and object constructors to understand and deploy locking and synchronisation at various levels, meant that they became too easily subject to deadlocks.

We opted for a message passing paradigm which allowed both application and object writers to essentially ignore locking and synchronisation issues and the SendMessage()/ProcessMessage() infrastructure took care of all that in a dependable manner while still allowing full advantage to be taken of asynchronism.

In practice, the perceived costs of message-ifying communications, were more than compensated for (in performance terms) by the avoidance of "belt&braces", unnecessary locking and sync-ing. In terms of reliability and programmer productivity, there was no contest.

So, my opinion is based upon experience, albeit possibly not entirely relevant experience, but I have followed your progress with interest, and open mind, and a desire to try out the results.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
  • Comment on Re^6: Overriding bless for inside-out object safety

Replies are listed 'Best First'.
Re^7: Overriding bless for inside-out object safety
by xdg (Monsignor) on Jan 04, 2006 at 21:13 UTC
    I am not convinced is that there is either a need for, or a benefit to, sharing objects between threads.

    Ah! I think I see the confusion. The protections are needed even without sharing objects between threads (where changes to an object in one thread are visible in another). Just creating a new thread can break any previously created inside-out object. In any new thread, inside-out objects that use a memory address as the "index" to the inside-out properties will break as the memory address changes. The new thread is a completely separate copy of all the data structures of the original and thus all the refaddr's change.

    use threads; sub dump { my $self = shift; print "name: ", $self->name(), "\n"; } $obj = Some::InsideOut::Class->new( name => "Larry" ); my $thread = threads->create( \&dump, $obj ); $thread->join();

    Without CLONE, $obj in the new thread won't point to the same data as in the original thread. CLONE gives an opportunity to fix up the data structures. Note -- this isn't using threads::shared; changes to $obj in the new thread wouldn't be seen in the original, but CLONE is still necessary.

    I'm not even tackling threads::shared support -- though jdhedden claims to have it working in Object::InsideOut, so it's apparently possible.

    I'm not sold on threads personally, but the real problem comes on Win32 where fork is really creating a thread. CLONE keeps Win32 fork safe for inside-out objects.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      The protections are needed even without sharing objects between threads (where changes to an object in one thread are visible in another).

      This is only true if

      • You create objects prior to spawning your threads
      • You attempt to reference or use those objects from multiple threads concurrently and expect them to remain consistent.

      I'm suggesting that neither of these is either desirable nor necessary for threaded applications provided you do not try to use threads as you would forks.

      I cannot address your comments regarding fork on win32. With the absence of proper signal emulation; the conflicts with global resources, file handles, sockets, environment, etc.; and the performance penalty that the fork emulation layers upon threading; I (personally) would prefer it if the fork emulation did not exist.

      In my attempts to use it, it simply isn't sufficiently compatible with Unix fork to make it usable in for the normal "forking idiom" (Silly forker :).

      Of more concern to me is that the requirements imposed by the attempted emulation, have a disastrous effect upon the use of threads as threads. It forces me to jump through hoops to avoid the expensive and unwanted automatic duplication of resources, to be able to get 'virgin' threads without pre-existing baggage.

      I realise that the emulation came first and threads (as in ithreads) leverage much of the excellent work that went into the original fork emulation, and I am not detracting from that work, but it would be so much better (for me, and my uses) if I could specify use threads qw[NOCLONE];.

      Ie. When I create a thread, give me a virgin interpreter running in that thread and let me create the things I need. Please :)

      I've never really understood the fork and exec idiom anyway. Why bother going through the process of duplicating the current process in to an exact clone--even with COW--if the next thing you are going to do is throw it all away and load a completely different executable image into that process? Why not just load the image into a new process and have done with it?

      I know fork & exec isn't the only use of fork, but it is the most prevalent.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        This is only true if...

        I can agree with that. However, in writing an inside-out helper for others, I feel I have to plan if not for the worst case, at least for many of the suboptimal practices that people may use. (Insofar as Perl will let me -- I can't do much about pseudo-forks on Win32 Perl 5.6.) So while I agree, it doesn't let me off the hook of helping people with automatic support for CLONE.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.