|No such thing as a small change|
one quote I remember was that Win32 will never have Unix-like signals because Dave shouted "signals are a crock".
I've also heard that one. And from memory, it was related to me by someone (who claimed to be) in the meeting at the time. Which is about as good a defintion of hearsay as I can think of, but it did reinforce my long term impression that if anything, NT went out of its way to trying to avoid borrowing anything at all from unix.
There are obviously many things that every OS has to have in common. And many more that are so obvious that when independent teams set out to solve the same problem, similar solutions are bound to arise.
Hence, virtual memory, developed by IBM (as Virtual Storage) for OS/VS and MVS is an integeral part of any modern OS, including *nix and NT, but it would be churlish to say that they borrowed (often written as "stole") the concept from IBM.
BTW, I'm not a fan of signals either and they certainly don't mix very well with threads.
One analogy I read about signals was imagine what would happen if your car just instantly stopped, frozen in place--mid-corner or wherever--when your mobile phone rang. Cos that's what signals do to your code. And that kind of speaks to the fundamental difference between *nix and NT.
for example, compare and contrast the many complex parameters and sub parameters of the Win32 CreateProcess call with Unix fork and exec.
The NT kernel was written from the ground up to me multitasking. The entire kernel was written to be reentrant. That is, all the of the state associated with a given process (actually, thread) is maintained within the auspices of that entity, or keyed by a handle specific to that entity. It is effectively object oriented, albeit it that the restrictions of C mean that it doesn't use object syntax at the API level so you have to manually pass the object reference (handle) to the relevant APIs manually.
This shows up (at the kernal API level) in such things as the pids, tids and fids; which are available but are mostly not used at the API level, where opaque handles are used instead.
Another example is memory buffers. In *nix, these are routinely allocated by the kernel and passed back to the application program. The Win32 API forces the application program to allocate the memory for the buffer and pass it's address into the kernel.
The advantages of this approach really show up when writing code that will live in a dynamically linked library, where the same code may be executing concurrently in the auspices of many threads and many processes.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.