Generally, however, processes don't get restarted after updates and libraries don't get reloaded, so without rebooting, you're still running the unpatched versions.
I don't know if RHEL has a clever way to figure out what needs to be restarted (it's not entirely impossible, thanks to systemd), but pretty much everyone under "et al." has this problem.
See Peter Larsen's comment here: https://lwn.net/Articles/702664/ for a more authoritative take on this, I deserted to BSD land long ago...
tl;dr Rolling out the updates without restarting is one thing, and it's done, and Microsoft could do it too, they just take the easy route. Applying them without restarting is a very different and far murkier story.
It's possible determine what processes run outdated library code. There are tools which hook into the package manager which do this, like https://github.com/liske/needrestart
This is a reasonable solution if you're running relatively non-critical processes on a single machine. If you really want to avoid downtime, a cluster with rolling updates seems like a solution with far fewer headaches.
Non-critical covers a lot these days, fortunately :-).
It'll eventually get reinvented :-).
However, the opposite problem - that of (thread-safely) ensuring that you're not stepping on another process' file when you're writing, wiping or moving it - is pretty tedious under Unix. The only way to do it reliably - that I know of - is via flock, which is opt-in and therefore not always an option (e.g. the other process is a third-party application that doesn't lock its files), and doesn't work on remote filesystems
There is no design decision without at least one compromise hanging on its tail.