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


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

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.

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

    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.

      The problem is that you insist upon taking a specific subject--on-topic in context of both the site and the thread--and injecting a generalised statement, based more upon prejudice and dogma, than reasoned argument, and stating your position in those terms.

      It does nothing to further the original discussion and serves only to provide a platform on which you can expound in the sure knowledge that your pro-unix, "windows is broken" stance will play to the gallery.

      An example;

      ...the key semantic that makes fork() so useful is that it allows inheriting the current execution environment to the child.

      This is a circular argument. With threads, you don't need to "inherit the current execution environment"--you already have it! Each thread is a complete execution enviroment. It can choose to be completely isolated and independant, or share exactly that which needs to be shared.

      The primary flaw in perl threads is that they attempt to emulate the fork mechanism in order to make fork & exec style idioms portable to the windows platform. The very thing that makes iThreads accusable of being "slow and memory hungry" is the that they insist upon attempting to duplicate the fork behaviour by replicating everything that exists at the point of spawn.

      Indeed, from my less than perfect historical view, this exactly how they came about. It's not that there is anything wrong with the fork behaviour where that is the "natural order of things"--it just doesn't work well where the OS does not support it natively. Laudible though portability is, it will always be a compromise.

      And it is unnecessary. If each thread was simply a clean, separate interpeter running in it's own thread in isolation of the others; with no "default" replication of anything; with only that which the programmer chose to share being shared; all of the problems would be completely negated.

      In this schema, shared data (and even objects) would exist in a single (hidden) thread. Accessing those shared entities from other threads would be transparent (via queued requests hidden behind tie's) from the user thread to the sharing thread. The tie/shared mechanism would perform all of the synchronisation and locking. The programmer would simple declare the shared entities as shared and use them, and everything else would be transparent.

      But that has as much relevance to anyone needing multitasking with bidirectional communications today as "slightly better IPC mechanisms than those invented decades ago"--none!


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

        ...the key semantic that makes fork() so useful is that it allows inheriting the current execution environment to the child.

        This is a circular argument. With threads, you don't need to "inherit the current execution environment"--you already have it!

        That's not the point. Ignore the choice of “inherit” per se; that is purely wording. I'll try to state it more neutrally yet:

        You want to be able to launch a new branch of parallel execution at some point in the program and you want both branches to start out with the same environment and state. You can just do that with processes when you have fork(); you need threads when you don't.

        Makeshifts last the longest.