Several decades ago, when people still used printed documentation (remember VMS and the blue wall, orange wall and gray wall?), I was working on software that needed to be run on both Linux and HP-UX (and we had hopes for SunOS and AIX too). I decided that instead of using the vendor documentation (which in the case of Linux meant: read the source code), I would buy the O'Reilly Posix books and use them as a guide. So I got the Posix.1 book, and Bill Gallmeister's Posix.4 book (for threads, locks, and real-time stuff like async IO). By the way, Bill is a great guy, fellow high school band parent, engaged in the community, but I digress. Any way, I developed my software following the Posix standard "to the letter". On HP-UX and the other commercial OSes this worked really well, and made portability a snap (the only remaining problems were makefile stuff and directory names, stuff like /usr/lpp versus /opt). On Linux, it didn't work. Even though Linux pretended to be Posix compliant (and had all the header files, and you could set all the compiler defines), stuff didn't actually work. My favorite example: RedHat had implemented the aio... calls in order to be Posix compliant, but they were actually not the slightest bit asynchronous, and were simply executed in the caller's thread synchronously in the foreground. I did some digging, and the story is that some software engineer at RedHat working on libc and librt got into a spat with a kernel developer about the correct interfaces for async IO (this was the time when the kernel was still developed by beer-drinking college students, this was around kernel version 2.0 and 2.2), so they decided to "fake" async IO in userspace, with threads. And because multi-threading wasn't working well yet (things tended to lock up when you had more than a dozen threads), the default number of worker threads for async IO was 1. That kind of problem can really only be dissolved in alcohol.