CS361: Operating System

Jian Huang — Spring 2012

EECS | University of Tennessee - Knoxville

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.

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-

       -  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).


       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
NPTL 2.5

Now, let's look at an excerpt from "man clone".

       #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 */ );


       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)

Jian Huang / EECS /UTK / revised 01/2012