5

I was prompted to ask this by another recent question about early Unix process structure.

The more-or-less contemporaneous systems I'm aware of (built 1960s to 1970s) mostly gave you a software structure, often called a 'job', when you signed on through a terminal. For commands not built in to the command interpreter, core would be allocated to the job, and the command program executed within the job.

I don't think Multics counts; my understanding is that the multiprocess approach was designed but not used.

TENEX used a multiprocess structure but I'm not sure it qualifies as first.

6

The idea of having a hierarchy of child processes(*1) and using a Fork like mechanic is quite tied to Unix as an operating system, but not originated there. To my knowledge it was Melvin Conway who first wrote in 1962 about a possible software structure based on a concept of "forking" and "joining" of processes to achieve parallel execution on multiprocessor systems. While forking one does not need any bookkeeping of process relation, the later process of joining (synchronizing) the execution does greatly benefit thereof.

Linus Nyman and Mikael Laakso mention in their 2016 paper Notes on the history of fork-and-join that Conway did remark that "the fork-join notion has been around for a while" before he wrote his paper. The first real implementation of this father-son relation was eventually done with Project Genie in 1964 by Laurence Peter Deutsch (*2) on a 24 bit SDS 940 machine. Project Genie inspired many others not at least TOPS-20. And the rest is history.

Or not. As to come to Unix' process structure it might be important to understand Multics view of process and memory. A process was for the most part a list of segments mapped into its address space. So far it may sound like any other OS, but Multics also tried to remove the idea of different storage levels by not acknowledging RAM as something in its own right, but always being a representation of a disk file. So not just Code, but each and every memory segment (during lifetime of a process) had to have an associated file. One where it could be saved to and loaded from.

Beside providing a stringent structure, it had several advantages. Libraries or utilities could be just called by dynamically creating a new segment assigned with the file name of the library in question and right away calling a function. The OS would then map the code, and execution continued. Having this, it was no big deal to invoke a new process the same way, by setting up a list of segments with associated file names (at least one with the code) and then initiating a new process with this segment list - while staying in memory and waiting for a return - or not.

Sounds complex and it is. Ken Thompson once called it "overdesigned and overbuilt and over everything" (*3) and I think he's right. Multics was conceived top-down with a huge theoretical overhead. Then again, he did like the idea of having an exchangeable shell (contrary to an OS built-in EXEC) and executing programs as separate processes while the shell (and thus all prior programs) stay in memory and wait. So long story short, the easy creation of new processes was kept while the tight coupling of memory and disk was thrown overboard for Unix.


*1 - There are many other ways to handle processes other than the Unix way, usually more loosely bound and/or using threading or interrupt level like scheduling, avoiding the hierarchical problems of fork-join.

*2 - Most well known due to his free Postscript implementation Ghostscript

*3 - P.463 on Peter Seibel's book Coders at Work

  • 2
    Fair enough, but process-per-command doesn't require the semantics of fork. The possibly more common paradigm of creating a new process with a new image (in one operation) will suffice. Nevertheless, the pointer to SDS940 is a good one. I'll need to go and refresh my memory of how it handled this. – another-dave Nov 23 '18 at 3:00
  • @dave Well, yes and no. Joining needs a clear coupling of the parent process and it's child. To show the line of development here, I added a few lines about multics and it's influence on Unix regarding process creation. – Raffzahn Nov 23 '18 at 3:37
  • 1
    By 'fork' I understand that the child process be created with a copy of the parent address space. Parent-child relationship, and in particular awaiting child termination, can and did exist without that. Whether you care to call that 'join' seems like a matter of taste. – another-dave Nov 23 '18 at 4:06
  • @dave Not realy, that is the meaning fork became after it was used by Unix - and Unix being the first OS that did so with a copy of the parent address space. As shown, the term 'fork' was used way before Unix and itself is not related to the copy part. Also, if this (child baing a copy of parent) is one of the requirements of your question, then Unix is the answer. If not, then Multics is a good candidate for an answer to the question in your title - and Genie maybe as well, except I do not know enough details to be complete sure. Maybe you want to better clarify what exactly you ask for – Raffzahn Nov 23 '18 at 4:16
  • OK, I'll agree to your opinion on the term 'fork'. Address-space copy is not part of the question. The question is really about getting a new 'container' for each command rather than putting the command in an existing 'container'. Counter-example: the TOPS-10 monitor ran programs in the user's single job. – another-dave Nov 23 '18 at 15:05

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.