I always believed that fork() was the very essence of the beauty of UNIX.
So simple, yet so powerful. And it is far simpler than its predecessor on
Genie, which looked a lot more like spawn().
With fork, the child inherits properties which may not have existed when
the code was written, so it's much easier to reason about the behavior of
sub-processes. Fork made writing the shell and pipelines much more obvious.
Today we know that threads and shared mutable memory are a really bad idea,
it's just that the hardware gave us no alternatives. I claim UNIX is
directly responsible for the existence of MMUs in microprocessors. What if
CPU designers would add facilities to directly implement inter-process or
inter-processor messaging? Sadly, there has to be a dominant software
paradigm for the hardware guys to target, so there's a nasty chicken and
egg problem. Imagine if the Erlang model of distributed systems had taken
off. Go gets us part of the way there, but cross-machine messaging is
still a mess.
On Tue, Aug 3, 2021 at 8:02 AM Douglas McIlroy <
douglas.mcilroy(a)dartmouth.edu> wrote:
fork() is a
great model for a single-threaded text processing pipeline
to do
automated typesetting. (More generally, anything
that is a
straightforward
composition of filter/transform stages.) Which
is, y'know, what Unix
is *for*.
It's not so great for a responsive GUI in
front of a multi-function
interactive program.
"Single-threaded" is not a term I would apply to multiple processes in
a pipeline. If you mean a single track of data flow, fine, but the
fact that that's a prevalent configuration of cooperating processes in
Unix is an artifact of shell syntax, not an inherent property of
pipe-style IPC. The cooperating processes in Rob Pike's 20th century
window systems and screen editors, for example, worked smoothly
without interrupts or events - only stream connections. I see no
abstract distinction between these programs and "stuff people play
with on their phones."
It bears repeating, too, that stream connections are much easier to
reason about than asynchronous communication. Thus code built on
streams is far less vulnerable to timing bugs.
At last a prince has come to awaken the sleeping beauty of stream
connections. In Go (Pike again) we have a widely accepted programming
language that can fully exploit them, "[w]hich is, y'know, what Unix
is 'for'."
(If you wish, you may read "process" above to include threads, but
I'll stay out of that.)
Doug