From: Eric Lee Green Date: 2001-11-28T14:57:27+09:00 Subject: [ruby-talk:26745] Fork, thread, etc. On Monday 26 November 2001 08:47 pm, MikkelFJ wrote: > > thread or process couldn't solve at least as well. Lets not forget that > > (IMHO) fork was really a workaround for not having threads. > > That is also my view Actually, fork() was created for a very simple reason: on a PDP-11, it allows you to have more than 64K worth of programs running. PDP-11's could have anywhere from 128K of memory to 758K of memory, but all instructions used 16-bit addressing. So the maximum size of any process or set of threads could only be 64K. But by creating a new process that ran in a different segment, you could use more of that memory, and also make it easier to do swapping (which was done a whole process at a time, since the first PDP-11's that Bell Labs bought had no MMU capable of paged virtual memory). The only real issue is why did they implement fork() rather than spawn(), but to a certain extent that was dictated by the use of pipes for inter-process communications and the problem of "how does our new process get the other end of this pipeline?". I have no idea why fork() was chosen rather than, e.g., passing some kind of special "environment" area for such purposes, except maybe simplicity of implementation (since an "environment" area would have required shared memory, which early Unix did not have). There are also some philosophical reasons behind the fork-vs-thread dichotomy. fork() enforces strict firewalls between components. thread() encourages interdependencies between components. Unix was designed under a philosophy of "many small tools chained together". The goal was to make each component an independently usable and runnable component. To a certain extent this was a reaction against Multics. In Multics, a user login was one big process, and all components were actually DLL's. Commands in Multics were the same thing as DLL's in Multics, except they had the equivalent of a main() entry in the DLL where running, e.g., the 'ls' command meant that the Multics shell went out and found the 'ls' segment, called the dynamic loader to map it into the process memory, then called the main() routine (a subroutine call). The subroutine when it did its return statement ended up back in the shell. There was also a crude stack mechanism for switching between running commands. The break key would call the equivalent of a Unix signal handler that called the shell (recursively now!). you could execute commands in this new shell, then exit back and start executing the previous command (or you could do a stack pop and kill that previous command, and end up back at the previous shell). All of this was immensely complex, and running commands could stomp over the shell or over other running programs on the stack, causing the whole login to lock up, at which point there was nothing to do except traipse over to the system operator's cubicle and beg for him to force-log you out. So there was a philosophical reaction against Multics that urged against the notion of running multiple things in a single process space, even if the practical aspects had been easily solvable on a PDP-11. The goal of strict "firewalls" between running programs was very alluring to the creators of Unix, because they'd experienced the worst of what could happen with running multiple things in one process with Multics (since Bell Labs pulled out of the Multics project before the OS was anywhere near stable). Disclaimer: I'm drawing upon 20-year-old memories here. Some recollections of how Multics or early Unix worked are bound to be wrong. The general nature of how they worked, on the other hand, should be fairly accurate, as well as general philosophical issues of the day (many of which appear ludicrous today -- e.g., when the first full screen editors appeared, they were widely derided as utterly impractical because no computer would ever be able to handle interrupts fast enough to handle more than 2 or 3 users, and of course personal computers? What a ludicrous idea!). -- Eric Lee Green GnuPG public key at http://badtux.org/eric/eric.gpg mailto:eric@badtux.org Web: http://www.badtux.org You do not save freedom by destroying freedom