http://qs321.pair.com?node_id=426410


in reply to Re^2: Isolating dynamically loaded modules with Thread::Isolate.
in thread Isolating dynamically loaded modules with Thread::Isolate.

I you don't need inter-task communications, then I agree, but the biggest problem people have with using threads is trying to use them in the same way that forks are used. This is true of whether using iThreads or pthreads, or most other forms of threading.

Just as Perl requires the adoption of a different way of working to C if you are to realise the best from it, so once you have relatively easy inter-task communications, a different way of working and thinking is called for.

And there are other platforms than the unix-like world.


Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.
  • Comment on Re^3: Isolating dynamically loaded modules with Thread::Isolate.

Replies are listed 'Best First'.
Re^4: Isolating dynamically loaded modules with Thread::Isolate.
by Aristotle (Chancellor) on Jan 31, 2005 at 10:46 UTC

    IPC is weakness of multiprocess models, and I'm disappointed that everyone has been content to stick to the same IPC mechanisms which have been around since day one. I'd rather prefer if the amount of effort that has gone into threads in the Unix world at large had gone into making it easier for forked processes to communicate when they need to. A highlevel language like Perl where variables are more than just names for memory locations offers particularly great opportunities to hide much of the drudgework of IPC from the programmer.

    Defaulting to no shared memory is inherently safer than defaulting to all memory being shared, and on modern CPUs with useful MMUs forking doesn't even cost a single extra cycle. Threads are implemented in terms of fork() in the Linux kernel.

    Threads are mainly useful as a way to regain some of the fork() semantics on amputated platforms that don't natively offer something equivalent. Indeed, the iThreads you so like, in various respects behave more like forked processes than like ye olde threads.

    Makeshifts last the longest.

      Threads are mainly useful as a way to regain some of the fork() semantics on amputated platforms that don't natively offer something equivalent. Indeed, the iThreads you so like, in various respects behave more like forked processes than like ye olde threads.

      Aristotle Quit doggin' me.

      A platform that chose a non-forking model of multi-tasking isn't "amputated", it just made different--I would contend, more modern and sensible; but don't let's get into that argument-- design-time choices.

      The biggest single problem with iThreads is that they attempt to emulated that model of operation.

      I simply try to make best use of what is available, and counter the (ongoing) FUD that they are unusable. And I think that I have demonstrated conclusively that used properly, they can be used very effectively.


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

        You have indeed demonstrated conclusively that in absence of better choices, iThreads are useful.

        I stand by my assertion that threads are only useful in the absence of fork(), and that this would be even more starkly obvious if there were just slightly better IPC mechanisms than those invented decades ago.

        I do also stand by polemically expressed assertion that a lock of fork() makes for an amputated platform, which is underpinned by the fact that proponents of such platforms usually like threads because they make it easier to coordinate parallelly executing pieces of code.

        If you feel compelled to counter positions you disagree with and decide to act on it, how does it reflect on you to tell someone else who is doing the exact same to “quit dogging” you? I happen to partially disagree with a number of positions you've defended recently; and you happen to often defend your positions ardently. I'd react just the same if someone else was arguing the same positions.

        To expound on the point in case it isn't clear what my argument is: the key semantic that makes fork() so useful is that it allows inheriting the current execution environment to the child. This is the facility which threads restore on a CreateProcess()/spawn() platform. I don't think anyone can reasonably argue that this facility is not incredibly useful. Server daemons on Unix are traditionally implemented with fork(); on Windows, they use threads: in both cases, for this exact reason. And that brings me the point: when there's a way to do that between processes, there's no need to invent a duplicate, less safe mechanism for parallel execution outside processes.

        Hopefully you can accept that as a clearly stated position (rather than just arguing for argument's sake), regardless of whether you agree with it (I have no illusions about that :-)).

        Makeshifts last the longest.

Re^4: Isolating dynamically loaded modules with Thread::Isolate.
by samtregar (Abbot) on Jan 31, 2005 at 03:54 UTC
    I you don't need inter-task communications, then I agree, but the biggest problem people have with using threads is trying to use them in the same way that forks are used. This is true of whether using iThreads or pthreads, or most other forms of threading.

    Frankly, my biggest problem with using threads in Perl is that the implementation isn't very good. It's slow, uses a ton of memory and has some very non-intuitive restrictions. It feels exactly like what it is - a second-rate feature added as an after-thought.

    -sam

      It's slow, uses a ton of memory

      The following code spawns 100 threads in under 2 seconds and uses < 40MB?

      >perl -Mthreads -le"print time;@t=map{threads->new(sub{sleep 300})}1.. +100;print time;<>" 1107144770 1107144772

      I agree they aren't doing much, and that is probably considerably slower than you can spawn 100 processes--but if you need the parent to communicate with the children and vice versa, then you'd need to a lot more work using fork.

      It is true that there are some inconvenient restrictions (some of which could be alleviated), and you do have to learn a few simple techniques for getting the best from them--like not loading anything you don't want shared before you spawn your threads--but they are stable and very usable.

      On Win32, they are infinitely preferable to fork, but I realise that that is a restriction of the platform. I can well see why anyone on unix wouldn't bother with them unless they really needed bi-directional communications.

      I agree that the implementation is imperfect, but having spent a little time looking into the work that they are doign, I think teh guys that got them to where they are are did an brillaint job given the task they faced.


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
        I suspect 100 forked processes that don't load any modules would use a lot less than 40MB, and it only gets worse for threads when you start loading enough modules to do something useful. The code and variable storage used by the modules will all be duplicated into every thread. With forking, copy-on-write prevents this. Forking is not great, but at this point it's a lot lighter than threads.