Threads
Thread Subpart of a process Basic unit of CPU utilization Smallest set of programmed instructions, can be managed independently by OS No independent existence (process dependent) Light Weight Process
Light Weight Process Process Single thread system Every process have its separate resources Heavy for memory Heavy for process context switching Heavy IPC Thread Threads have own resources and shared Threads of a process share resources Light for memory Light for thread context switching Light ITC
Advantages of multithreaded system Responsiveness Resource sharing Code, process resources, address space Economy Utilization of multiprocessor architectures
Types of Threads User threads User level library Kernel threads Kernel space
User level threads Created and managed in user space The kernel is not aware of thread activity but it is still managing process activity Thread switching does not involve the kernel Scheduling can be application specific ULTs can run on any OS -- Only needs a thread library For a single kernel process, they cannot be distributed among multiple processors. I/O or other blocking system call has to be replaced with non-blocking system calls. kernel can only assign processes to processors
Kernel Level Threads Created and managed in kernel space by kernel Slower to create and to manage If a thread performs a blocking system call, the kernel can schedule another thread in the application for execution.
Implementing Threads in User Space
ULT Idea Thread management done by user-level threads library. Threads library contains code for: creating and destroying threads. passing messages and data between threads. scheduling thread execution. saving and restoring thread contexts. Three primary thread libraries: POSIX Pthreads Win32 threads Java threads
POSIX Pthreads A POSIX standard (IEEE 1003.1c) API for thread creation and synchronization. May be provided either as ULT or KLT. API specifies behavior of the thread library, implementation is up to development of the library. Common in UNIX operating systems (Solaris, Linux, Mac OS X).
Some of the Pthreads function calls
Kernel activity for ULTs The kernel is not aware of thread activity but it is still managing process activity. When a thread makes a system call, the whole task will be blocked. But for the thread library that thread is still in the running state. So thread states are independent of process states.
Advantages and inconveniences of ULT Advantages Thread switching does not involve the kernel: no mode switching. Scheduling can be application specific: choose the best algorithm. ULTs can run on any OS. Only needs a thread library. Inconveniences The kernel blocks processes. So all threads within the process will be blocked. The kernel can only assign processes to processors. Two threads within the same process cannot run simultaneously on two processors.
Thread Library Creating and destroying threads Passing messages and data between threads Scheduling thread execution Saving and restoring thread contexts
Implementing Threads in the Kernel
Advantages and inconveniences of KLT Advantages the kernel can simultaneously schedule many threads of the same process on many processors. blocking is done on a thread level. Inconveniences thread switching within the same process involves the kernel. We have 2 mode switches per thread switch. this results in a significant slow down.
Hybrid ULT/KLT Approaches Thread creation done in the user space. Bulk of scheduling and synchronization of threads done in the user space. The programmer may adjust the number of KLTs. May combine the best of both approaches. Example is Solaris prior to version 9.
Hybrid Implementation Multiplexing user-level threads onto kernel-level threads.
ULT, KLT and Combined Approaches
Multithreading Models Many-to-One One-to-One Many-to-Many
Many-to-One Many user-level threads mapped to single kernel thread. Thread management is done in user space. Used on systems that do not support kernel threads. Since only one thread can access kernel at a time, multiple threads are unable to run in parallel on multiprocessors.
Many-to-One Model
One-to-One Each user-level thread maps to kernel thread. More concurrency. Every user thread requires creating a corresponding kernel thread. Examples - Windows 95/98/NT/2000 - Linux
One-to-one Model
Many-to-Many Model Allows many user level threads to be mapped to many kernel threads. The number of kernel threads may be specific to a particular application or particular machine. (More kernel threads on a multiprocessor m/c) Allows the operating system to create a sufficient number of kernel threads. Solaris 2, IRIX, HP-UX
Many-to-Many Model
Thread Implementation Creating a (Default) Thread pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
Cont #include <pthread.h> pthread_attr_t tattr; pthread_t tid; extern void *start_routine(void *arg); void *arg; int ret; /* default behavior*/ ret = pthread_create(&tid, NULL, start_routine, arg); /* initialized with default attributes */ ret = pthread_attr_init(&tattr); /* default behavior specified*/ ret = pthread_create(&tid, &tattr, start_routine, arg);
Cont When pthread_create is successful, the ID of the thread created is stored in the location referred to as tid. pthread_create() function is called with attr. pthread_create() returns a zero and exits when it completes successfully
#include <pthread.h> pthread_t tid; int ret; int status; /* waiting to join thread "tid" with status */ ret = pthread_join(tid, &status); /* waiting to join thread "tid" without status/* ret = pthread_join(tid, NULL);
The pthread_join() function blocks the calling thread until the specified thread terminates.
void mainline (...) { struct phonebookentry *pbe; pthread_attr_t tattr; pthread_t helper; int status; pthread_create(&helper, NULL, fetch, &pbe); /* do something else for a while */ pthread_join(helper, &status); /* it's now safe to use result */ } void fetch(struct phonebookentry *arg) { struct phonebookentry *npbe; /* fetch value from a database */ npbe = search (prog_name) if (npbe!= NULL) *arg = *npbe; pthread_exit(0); } struct phonebookentry { char name[64]; char phonenumber[32]; char flags[16]; }