https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...
https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...
[0] http://pubs.opengroup.org/onlinepubs/009695399/functions/pos...
fork()/clone() obliges you to track which things the child doesn't want from the parent, and have a way to override them
CreateProcess obliges you to track which things the child DOES want from the parent, and have a way to override them.
There's a convergent evolution at work, the same way bats and birds have both got wings without a common ancestor having wings, wings work, not quite the _same_ wings, but the idea works, so it's inevitable.
futex() and WaitOnAddress have the same funhouse mirror effect. They're doing the same exact thing (very, very cheap synchronisation primitive, with just barely enough features to be useful), the names and descriptions are really different, but if you use both you're like "Oh, these are basically the same, huh". Both names are equally useless, futex() is a clever name if you already know what it does, but until you do you've no idea what to look for. On the other hand WaitOnAddress doesn't actually er, wait on an address, that would be expensive, like futex waking it up when something changes is _your_ job as the programmer.
The elegance of fork() is in avoiding the complexity of requiring every attribute of the process to be explicitly stated in order to create a new process. We simply inherit our parent's attributes and if that turns out not be desirable it is fixed in the child with the usual syscalls.
EDIT: s/And/Or set/
It would be interesting to see in what ways Unix (especially shell scripts) would be different if processes would not inherit all the baggage by default.
So really fork is the opposite of elegance. It makes state implicit, not explicit.
Nowadays, I think ‘whitelisting’ what the new process can do is the choice to make, not forking and then (hopefully) ‘blacklisting’ what you don’t want (that’s especially important if you eventually will be running code you didn’t write or, maybe, don’t even have source for)
That also is easier to test for. If you forget to specify a capability before forking, the bugs you see will be better reproducible than when you forget a thing you don’t need.
I can’t find it now, but try googling an article on how to properly fork a process nowadays. It is insanely difficult to do right.