N:M implementation of POSIX Threads API
I was reading through the pthreads man page (https://man7.org/linux/man-pages/man7/pthreads.7.html) trying to understand how pthreads is implemented. For linux, pthreads library can be thought of as a wrapper over the kernel syscalls (`clone` and `futex`). The manual goes on to talk about the NPTL implementation which is a 1:1 implementation i.e. it uses 1 kernel thread for each pthread-created-thread.
This raises, I believe, a natural question, that could there be any implementation of pthreads, perhaps in other operating system, that uses a different scheme (N:1 or N:M). i.e. could multiple pthread-created-threads be run by a single (or multiple) kernel threads by using cooperative multitasking or other techniques in user space.
I am aware of Green Threads (also known as coroutines, or user space threads) and have played a little with coroutines in the Go programming language. I have also found that such concept exist in other languages like Erlang, Elixir. So, the question is not that whether N:1 is possible, but whether
- if such implementation would still be POSIX Thread specification compliant.
- And if so, are there any attempts for that in C language.
I believe the answer to 1 is Yes. (Also indicated by Thread Implementation Models section in https://pubs.opengroup.org/onlinepubs/7908799/xsh/threads.html). As for 2, I couldn't find any such implementation by searching on the internet.
The following is the excerpt from the pthreads manual that triggered the above thought.
Linux implementations of POSIX threads Over time, two threading implementations have been provided by the GNU C library on Linux:
LinuxThreads This is the original Pthreads implementation. Since glibc 2.4, this implementation is no longer supported.
NPTL (Native POSIX Threads Library) This is the modern Pthreads implementation. By comparison with LinuxThreads, NPTL provides closer conformance to the requirements of the POSIX.1 specification and better performance when creating large numbers of threads. NPTL is available since glibc 2.3.2, and requires features that are present in the Linux 2.6 kernel.
Both of these are so-called 1:1 implementations, meaning that each thread maps to a kernel scheduling entity. Both threading implementations employ the Linux clone(2) system call. In NPTL, thread synchronization primitives (mutexes, thread joining, and so on) are implemented using the Linux futex(2) system call.