in reply to Re: point #4
in thread Thoughts on how to devise a queryable win32 service

My first question is, where did you read that, because I would like to read that too. Indeed, this is an open invitation to anyone to /msg me links to any Perl + threads articles and discussions anywhere they see them. Really. Please send me any links you have. I will even commit to producing and maintaining a list of such links, including adding some assessment rating of the information they contain.


Are you saying that ...

Whoa! I'm not saying anything that contradicts any better information you can find, or knowledge you have.

Anything I say relates only to that experience I have personally acquired--plus some speculations based upon them; other experience; and logic.

Now, getting back to what I did say:), how I arrived at that statement, and it's implications:


Perl may use internal locking when modifying it's own internal use datastructures, such that it will prevent multiple, concurrent accesses, even if the user does not employ user locks correctly. This appears to be the case based on my experience, but I have yet to read a good description of what internal mechanisms of ithreads and sharing do, so I can only base my understanding upon my experiences, and what little I can glean from reading the sources--and that is very little! Perl's sources are scantly documented and very complicated.

The upshot of all of that is, that in my experiments with iThreads (since circa 5.8.3, on my single cpu machine), I have found it impossible to cause Perl to segfault through performing multi-threaded accesses to shared data elements even without user locks being employed. Nor have I been able to detect any inconsistancy of state.

This implies that Perl does employ internal locking to prevent internal inconsistancies, which makes sense, but I do not recall seeing this written down anywhere.

But I have not used Perl on an SMP box, so there is a chance that for all my emperical testing, I've only been "getting away with my abuse of not employing user locks consistantly", because I'm only really able to run one thread at a time.

It makes sense (to me), that Perl would employ internal locking to ensure the correct state of it's own interal structures. Which would mean that users only need to employ user locks if they are maintaining state across multiple Perl variables.

Example:. If I am using a Perl array to represent a stack, and rather than having perl remove elements "popped" from the stack, I am maintaining a separate "stack pointer" in a scalar, then when a new value is pushed to the stack, there are two operations required.

  • One to add the value at stacktop.
  • One to increment the stackpointer.

    Perl has no knowledge of the association between these two variables and so cannot perform locking to ensure their consistancy, so this would require a user lock. One lock variable used to serialise access to both the array and the scalar.


    Speculation warning!!

    Based upon my experiments, my supposition is that the user need never apply locks to individual shared variables to ensure their internal consistancy. Perl appears to do this internally.

    They only need to employ user locks if they wish to ensure consistancy of state between 2 or more perl variables.


    This makes perfect sense, and fits with my experience of using iThreads--but nowhere I have seen, is this written down!

    Indeed, all the documentation relating to sharing and locking shows individual locks being applied to individual variables. All of it! But this doesn't make sense if Perl is already employing internal locking to protect it's internal consistancy! It achieves nothing apart from to slow the program down.

    My assumption above, fits the data from my experiments,, but the complete lack of engagement from anyone who really understands what is going on internally means that my experiments, limited as the are to my single-cpu machine, are the only information I have upon which to draw conclusions.

    This is why I have resolutely resisted writing any tutorials, or making any meditations on the subject of iThreads. The total lack of engagement or writings by those (few) with real knowledge of what goes on internally to iThreads, (as opposed to a few others like me who played with them and drew conclusion based upon their experiments), means that anything I (or they) write is basically guesswork.

    Contrary to popular opinion that threads a unreliable, memory hungry or otherwise dangerous, the current, woeful state of that little documentation that does exist is the strongest argument for avoiding using threads in a production environment.

    Whilst I am happy to share snippets of code, opinion and advice with individuals on individual problems related to iThreads, I am not going to make the same mistake as others, and commit to writing something that gets transmitted around the world, and then referenced, quoted and re-quoted--by people who do not understand and have only second-hand knowledge and no direct experience--as authoratative.

    So, if you have an application for iThreads, and would like a little help in developing it--and especially if you are developing for a non-win32 platform (pref.linux), and especially, especially if you are using a multi-cpu machine--then I am more than happy to try and help you get it going. If you will provide me with feedback and maybe try a few things out along the way, that would be even better.

    But if you want me to commit to saying anything authorative about iThreads, beyond that which I have tried and tested within my own limited environment, you are out of luck :)

    Now, what was that you were saying about queues?


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
    • Comment on Re^2: point #4 (Now what was that you were saying?)
  • Replies are listed 'Best First'.
    Re^3: point #4 (Now what was that you were saying?)
    by perlhaq (Scribe) on Feb 10, 2005 at 16:33 UTC
      Ok, I found it. It's in the perlthrtut man page that comes with Perl 5.8.5. At the end of the section titled "Shared And Unshared Data", it says:

      Note that a shared variable guarantees that if two or more threads try to modify it at the same time, the internal state of the variable will not become corrupted. However, there are no guarantees beyond this, as explained in the next section.

      And the next section describes some typical race condititons one might encounter (two threads trying to read, then increment the same variable).
      So anyway, that text has led me to believe that a shared array used to implement a queue for passing data between threads would be safe, even with no locking, since the push() and shift() operations would be atomic in nature.
      If this doesn't apply to SMP machines though, then I've got some code to fix...

        Thankyou for taking the time to find it again.

        It's also nice to have my observations confirmed, and to see that it is mentioned in the documentation somewhere.

        It would be nice it also got a mention in the threads::shared POD, along with a few examples of when lock needs to be used and when not. I'll try to produce a docu-patch for that.

        So anyway, that text has led me to believe that a shared array used to implement a queue for passing data between threads would be safe, even with no locking, since the push() and shift() operations would be atomic in nature.

        I've generally use Thread::Queue for implementing queues between threads. I tried it early on and it has never given me a problem, so I've stuck with it.

        Re-reading perlthrtut, I agree with your reading that push and shift should be safe for this purpose. I'll probably have a play and see if I can break them.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.