Multi-threading models
The support may be provided at either the user level, or by the kernel for kernel threads. Users threads are supported without kernel support, kernel threads are supported and managed directly by the operating system.
The mapping between user threats and kernel threads can occur in 3 ways.
- Many-to-one model: In this model thread management is done by the thread library in user space. In essence the thread library provides all of the scheduling support
- One-to-one model: In this case user level thread are mapped to kernel threads on the one to one basis. Linux and Windows both implement this model
- Many to many model: Many users threats are mapped to a smaller or equal number of kernel threads. In theory, this model does not have to impose a limit on how many users threats can be created, and the kernel threads can be directly mapped to multiple processors. When this model is used together with one-to-one model-this mixture is called to level model of scheduling. This was idea had a great flexibility, was actually used in Solairs 9, but later deprecated.
Thread libraries
There are three major thread libraries: pthread, Win32 thread, and the Java thread. The 1st two are real operating system thread libraries. Java thread is implemented using either pthread or Win32 threads.
Thread pool is a concept where a number of threads are created when the process starts up, these threads sit and wait for work, when a request comes and if the thread is available the thread is passed to the request for use. Once the thread completes the service, it returned to the pool.
Other complex issues with threat library include (i) how threads can be canceled, (ii) upon forking - are all the threads copied over, and (iii) for signal handling, whether the signal is passed to all threads or passed only to the 1st thread that has not blocked the signal.
Linux implementation of pthread
On linux, the systems call clone() provides the basis of its threads library. Note, this syscall is linux specific, not available on other flavors of Unix. From the output of "man pthreads":
--- ... 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 (now obsolete) Pthreads implemen- tation. - 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 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 synchronisation primitives (mutexes, thread joining, etc.) are implemented using the Linux futex(2) system call. Modern GNU C libraries provide both LinuxThreads and NPTL, with the latter being the default (if supported by the underlying kernel). ... ... NPTL With NPTL, all of the threads in a process are placed in the same thread group; all members of a thread groups share the same PID. NPTL does not employ a manager thread. NPTL makes internal use of the first two real-time signals; these signals cannot be used in applications. NPTL still has a few non-conformances with POSIX.1: - Threads do not share a common nice value. Some NPTL non-conformances only occur with older kernels:
What is my linux box using? Hmm:
UNIX> hostname seelab.eecs.utk.edu UNIX> getconf GNU_LIBPTHREAD_VERSION NPTL 2.5
Now, let's look at an excerpt from "man clone".
SYNOPSIS #include < sched.h > int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... /* pid_t *pid, struct user_desc *tls, pid_t *ctid */ ); DESCRIPTION clone() creates a new process, in a manner similar to fork(2). It is actually a library function layered on top of the underlying clone() system call, hereinafter referred to as sys_clone. A description of sys_clone is given towards the end of this page. Unlike fork(2), these calls allow the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and the table of signal handlers. ... The main use of clone() is to implement threads: multiple threads of control in a program that run concurrently in a shared memory space. flags may also be bitwise-or’ed with zero or more of the following con- stants, in order to specify what is shared between the calling process and the child process: CLONE_PARENT (since Linux 2.3.12) CLONE_FS CLONE_FILES CLONE_SIGHAND CLONE_VM ...