in reply to Re^3: Multithreading, how to?
in thread Multithreading, how to?

Again, I don't disagree with you with regard to threading in general.

I do like the imagery though. Despite the fact that a kindergarten teacher may be able to get a group of 5 year olds to work together to accomplish some relatively impressive things, that does not mean that any random adult can do the same.

The problem with this analogy, as with the musicians, is that programs do not have minds of their own; and so are not subject to variable skill levels, PMS, hangovers, distraction by the musician in front's flimsy or tight clothing, or any of the other factors that can distract and disrupt human beings.

With code, once the right steps are codified and verified, the computer will happily perform those steps over and over precisely without getting bored, tired or distracted. The same does not hold true for human beings.

Once a piece of code, say a subroutine, is tested to work correctly as a single threaded, standalone environment, it will continue to work correctly when you run multiple copies of it concurrently. Provided that there are no unintentional interactions between the copies.

And it is in exactly that last area where iThreads are pretty much unique relative to most other forms of threading. The core concept that distinguishes them is that you have to explicitely arrange for anything to be shared. If you share nothing, there can be--barring errors in the core implementation; which do crop up occasionally in this field just as they do in every other field--no accidental interactions.

That single fact alone makes iThreads different from most other forms of threading.

The second major flaw in the multiple persons analogy is that with few exceptions, the success of human group activieties is dependant upon the management, coordination and timing of the interactions between the individuals. Hence the 'teacher' & 'conductor' roles in those analogies.

Whilst there are tasks that can benefit from multitasking that require such a coordinating and synchronising role, there are also whole classes of applications that do not. Collectively termed data-parallel, for which applying iThreads multi-threading to well-tested, single-threaded code requires minimal changes and (almost) no knowledge of the deep voodoo that is required to use other forms of threading.

I wrote my first threaded code--under OS/2--circa the late 80's under OS/2, and have made most of the mistakes--often multiple times! I've been involved in both successful and unsuccessful projects that used extensive kernel threading, but using iThreads has taught me things that I never seen described anywhere in the literature.

The most important of those lessons is that the easiest way to avoid the well-known problems of deadlocking, priority inversion et al. is to simply avoid using the mechanisms that lead to them. It sounds too simple to be true, but in the vast majority of the use cases I have explored, I've found relatively simple and reliable solutions that use iThreads, Queues, minimal shared data and minimal locking.

And in the few non-perl threaded applications I've been involved in since getting familiar with iThreads, I've found that lesson transfers quite well to other languages like C(++), Clean and more.


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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^5: Multithreading, how to?
by gwadej (Chaplain) on Dec 31, 2008 at 19:59 UTC
    With code, once the right steps are codified and verified, the computer will happily perform those steps over and over precisely without getting bored, tired or distracted. The same does not hold true for human beings.

    However, even in the single threaded case, code can appear to work for a long time (potentially years) and eventually fail because it was not coded correctly. While the code may not get bored or distracted, changes in its environment can make it fail intermittently. This is, of course independent of concurrency considerations.

    If you share nothing, there can be--barring errors in the core implementation; which do crop up occasionally in this field just as they do in every other field--no accidental interactions.

    Unless I misunderstand, though the separate threads still share the same file system, sockets, environment, etc. many of which are subject to cause interactions if the programmer is not careful. If I'm understanding the issue correctly, iThreads make memory non-shared by default. While the threads are more isolated this way, they are not completely independent.

    The second major flaw in the multiple persons analogy is that with few exceptions, the success of human group activieties is dependant upon the management, coordination and timing of the interactions between the individuals. Hence the 'teacher' & 'conductor' roles in those analogies.

    I obviously missed something in my explanation. I was not seeing the conductor or teacher as portions of the threaded code, the programmer is in the position of the 'teacher' or 'conductor' in these analogies.

    Let me try another way.

    In most single threaded programs, the programmer can lay out a sequence of steps with appropriate control logic. You can pretty much see how the code will run from beginning to end. (More complicated problems make this harder to see, but bear with me for a moment.)

    In a multi-threaded program, on the other hand, the programmer builds smaller, independent sequences of steps that run under their own control. Any place that these threads need to interact is not under the direct control of the programmer. So the programmer is kind of one step removed from the code. This makes understanding the interactions and timing (for lack of a better word) more important in this style than in single threaded code.

    It's been my experience that many people find this harder. Or they code assuming that things will behave the way they want (like it did in the single threaded model). These people are often stumped when their code doesn't work.

    Obviously, the fewer the interactions between the threads (not accessing shared resources and such), the less the coordination issues will affect us. If there's no interaction between the threads, then I wonder why they are in the same program.

    The most important of those lessons is that the easiest way to avoid the well-known problems of deadlocking, priority inversion et al. is to simply avoid using the mechanisms that lead to them. It sounds too simple to be true, but in the vast majority of the use cases I have explored, I've found relatively simple and reliable solutions that use iThreads, Queues, minimal shared data and minimal locking.

    These are the lessons I also learned from multi-threading work, even without iThreads from the mid 90s. But, these approaches do not always come naturally when someone tries threads for the first time.

    I guess that is what I've been trying to say (but have only done so badly). Multi-threading and single threading benefit from somewhat different viewpoints and tool sets. Someone doing threads for the first time should be aware that the different tools and viewpoints may be needed.

    G. Wade

      I hope you don't object to me continuing this discussion? I find debate the best way for me to clarify my own views and opinions--and you debate well.

      That said, I'm going to be lazy here and summarise(*) your post above.

      (* I mean 'precisé', but I'm unsure of the correct spelling. I know that last grapheme is incorrect, but I don't know how to produce (what I think) is the correct one.)

      I'll summarise it as: "Threading is hard, especially for beginners. It will require you to think differently and use different tools. You may find it easier not to try."

      That is an unfair simplification of the position you have expressed in the preceding posts. But not by much.

      Programmers have an inherent bias that leads them to believe and express that what they do is hard. It makes sense. It is good for business, and good for salaries. But ostensibly, relative to other technical fields, it is entirely wrong. Or at least, overstated.

      Learning to drive is a radical departure from anything you are likely to have done before you do it. It doesn't just require hand-eye coordination, but rather hand-eye-foot-brain coordination. But more importantly, it requires anticipation of the actions and reactions of others. Whilst some other activities--sports; computer games etc--exhibit similar requirements, the difference is that mistakes when driving are not just sometimes lethal, but frequently so.

      By contrast, programming is essentially benign. Barring the extremes--nuclear power plants; weapon systems; medical equipment--programming errors are seldom lethal. And even in those extreme cases where they can be, they can in most cases be mitigated by proper and conscientious testing.

      The point I'm trying to make is that everyone has to start somewhere. And regardless of the complexities of the task undertaken by a programmer, there is always a learning curve involved. But unlike many other fields of endeavour, programmers have the inherent benefit of being able to test the effects of their skills, prior to putting them into potentially lethal practice.

      Sure, threads are different. Threading can be hard. But neither fact should be lauded as a reason to preclude anyone from trying to acquire the requisite skills.


      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.

        I don't mind. I've found this to be an interesting discussion as well. I appreciate the compliment, although most people would just say I'm stubborn.<grin/> You've already convinced me I need to spend more time with iThreads. I look forward to what else I'll learn.

        I am surprised by how badly I'm apparently expressing my position on threads. This is shown by your summary.

        I'll summarise it as: "Threading is hard, especially for beginners. It will require you to think differently and use different tools. You may find it easier not to try."

        I pretty much agree with everything but the last sentence. I don't think I said you shouldn't try anywhere. I just suggested that it was not a trivial exercise.

        Your driving description actually sets up a perfect example of what I'm trying to say. When someone first wants to drive, we do not hand them keys and point them to the freeway for them to figure it out. Way back when I learned to drive, we started in an empty parking lot, with very little to run into.

        In much the same way, I think it is important to understand that a person's first threading project should be a pilot or test project. Adding threads to an existing project can be akin to putting someone in the drivers seat on the shoulder of a freeway and telling them to drive home.

        To take your example a bit further, (I've never been one to stop stretching an analogy until it hurts.<grin/>) I would compare single-thread programming to walking and multi-threaded programming to driving. When driving, you are not focused on staying balanced and watching where you put your feet. You need to be aware of much more:

        • the boundaries of your vehicle
        • your speed
        • the relation of the movement of your feet and hands to the movement of the vehicle
        • the vehicles around you
        • the road surface

        Once someone becomes proficient at driving, much of this awareness becomes unconscious. (You don't have to think about moving about foot motions when you want to slow down.) To someone new to driving, this is a whole lot to keep up with.

        Also like the driving analogy, I would never suggest that someone not learn to drive, just because it is very different from walking. But, I wouldn't think its appropriate to tell someone to just try driving on a 100 mile trip on their first attempt. Driving and threading are both useful skills, that are appropriate when you need them. But, they both require learning, practice and a new set of skills.

        Without knowing the problem the OP is trying to solve, I couldn't recommend threads as the right solution. Any more than I would recommend driving without knowing where someone needs to go (and what the terrain looks like.)

        That comment was what I thought I was supporting in your first response.

        G. Wade

        I mean 'precisé', but I'm unsure of the correct spelling

        First person future tense would be "préciserai", but does it makes much sense to use French verb conjugations in English? You can "write a précis", however.
        I can think of several problems with your driving analogy but I think they are rooted in two different things -- we have instincts related to movement/motion and we get real-time sensory feedback while driving.

        Meanwhile, for programming, beyond syntax highlighting there is no real-time sensory feedback. It's also not clear to me what instincts -- if any -- we have that help with programming. Puzzle solving comes to mind but that's is more like a trait than an instinct.

        Cooking may be a better analogy, but even it suffers from some real-time sensory feedback.

        This has been an interesting thread though. Thanks!

        Elda Taluta; Sarks Sark; Ark Arks