Chapter 4 - Threads
Chapter 4 - Threads
Multithreaded Programming
4-Threads 1
Recall the Main Concepts Behind Processes
1. Resource Ownership
– Virtual address space to hold the process image
➢ Program
➢ Data
➢ Stack
➢ Attributes
– OS shields processes from interfering with each others resources
➢ Protection
2. Scheduling/ Dispatching
– Execution may be interleaved with other processes
– Maintain execution states, etc.
4-Threads 2
Processes and Threads
Multithreading: More than one entities can possibly execute in the same
resource- (i.e., process-) environment (and collaborate better)
• Unit of dispatching
– Referred to as a
thread
• Unit of resource
ownership
– Referred to as a
process or task
4-Threads 3
Processes vs. Threads
• Process characteristics
– A virtual address space
➢ Holds the process image
– Global variables, files, child
processes, signals and signal
handlers
4-Threads 4
Processes vs. Threads
• Process characteristics
– A virtual address space
➢ Holds the process image
– Global variables, files, child
processes, signals and signal
handlers
• Thread characteristics
– An execution state, stack and
context (saved when not running)
– Access to the memory and
resources of its process
➢ All threads of a process share this
– Some per-thread static storage for
local variables
4-Threads 5
Processes vs. Threads
4-Threads 6
Processes vs. Threads
Address space/Global Variables
Open files
Child processes
Accounting info
Signal handlers
Program counter
Registers
Stack In case of multiple threads
State per process
Split
Unit of Execution/Dispatch
Unit of Resource
Program counter
Address space/Global
RegistersProgram cou nter
Variables Stack Registers
Open files State Stack Program counter
Child processes Registers
Share State Stack
Accounting info
Signal handlers State
4-Threads 7
Benefits of Threads
• Easy/Lightweight Communication
– Threads within the same process share memory and files
– Communication does not invoke the kernel
4-Threads 8
Uses of Threads
⇒Increase throughput
in message processing
4-Threads 9
Multithreaded Server Architecture – Example
4-Threads 10
Effect of Suspension/Termination
4-Threads 11
Implementing Threads in User Space
4-Threads 12
Implementing Threads in User Space
4-Threads 13
Example: User-Level Thread Execution
4-Threads 14
Example: User-Level Thread Execution
4-Threads 15
Example: User-Level Thread Execution
4-Threads 16
Example: User-Level Thread Execution
4-Threads 17
User-Level Thread
Advantages Disadvantages
4-Threads 18
Implementing Threads in Kernel/Lightweight Process
• Windows XP/2000
• Solaris
• Linux
• Tru64 UNIX
• Mac OS X
4-Threads 20
Kernel-Level Thread
Advantages Disadvantages
4-Threads 21
Some Performance Data
4-Threads 22
Multithreading Models: Many-to-one Model
4-Threads 23
Multithreading Models: One-to-one Model
4-Threads 24
Multithreading Models: Many-to-Many Model
4-Threads 25
Windows: Threads and Processes
Collection of
Jobs WIN32 API
processes
Kernel-level CreateThread
Thread Thread Thread threads ExitThread
User-level CreateFiber
Fiber Fiber Fiber threads ExitFiber
SwitchToFiber
4-Threads 26
Windows XP: Threads and Processes
• The register set, stacks, and private storage area are known as the
context of the threads
4-Threads 27
Windows XP: Threads and Processes
4-Threads 28
Linux Task Management
4-Threads 29
Linux Task Management
• fork() and clone() system calls
• clone() takes options to determine sharing between parent and
child tasks
4-Threads 30
Linux Task Management
• Unique kernel data structure (struct task_struct) for each task
– Instead of storing data, contains pointers to other data structures
– For example, data structure that represent
➢ open files
➢ Signal handlers
➢ Virtual memory
4-Threads 31
Thread Libraries
4-Threads 32
Thread Libraries
• Java threads
– Supported by the JVM
– Java thread API is implemented using a thread library available on the
host operating system, e.g., Pthreads, Win32
4-Threads 33
Pthreads API Overview
4-Threads 34
Thread Creation
4-Threads 35
Thread Creation
pthread_t *thread_id
• Hold the identifier of the newly created thread
• Caller can use this thread ID to perform various operations
4-Threads 36
Thread Creation
int pthread_create (pthread_t *thread_id,
const pthread_attr_t *attributes,
void *(*thread_function)(void *),
void *arguments);
pthread_attr_t *attributes
• Used to set thread attributes
• To create thread with default attributes
– Attribute object is not specified, i.e., NULL is used
• Default thread is created with following attributes
– It is non-detached (i.e., joinable)
➢ Detached: On termination all thread resources are released by OS
– It has a default stack and stack size
– It inherits the parent's priority
4-Threads 37
Thread Creation
void *(*thread_function)(void *)
• The C routine that the thread will execute once it is created
4-Threads 38
Thread Creation
void *arguments
• Arguments to be passed to thread_function
• Arguments must be passed by reference and cast to void*
• These pointers must be cast as pointers of type void
4-Threads 39
Thread Creation: Example
#include <pthread.h>
#define NUM_THREADS 5
int main() {
pthread_t threads[NUM_THREADS];
int rc, t;
for(t=0;t < NUM_THREADS; t++) {
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
}
4-Threads 40
Possible Output Sequence
• No deterministic execution!
– Thread execution can interleave in multiple ways
Possible Output
In main: creating thread 0
In main: creating thread 1
Hello World! It's me, thread #0!
In main: creating thread 2
Hello World! It's me, thread #1!
Hello World! It's me, thread #2!
In main: creating thread 3
In main: creating thread 4
Hello World! It's me, thread #3!
Hello World! It's me, thread #4!
4-Threads 41
Thread Creation
• Once created, threads are peers, and may create other threads
– No implied hierarchy or dependency between threads
4-Threads 42
Thread Termination
4-Threads 43
Thread Termination
4-Threads 44
Thread Termination: Example
#include <pthread.h>
#define NUM_THREADS 5
4-Threads 46
Passing Arguments to Threads
pthread_t pthread_self(void);
4-Threads 49
Changing Thread Attributes
Pthread_attr_t attr;
int main() {
pthread_t threads[NUM_THREADS];
int rc, t;
size_t stacksize
pthread_attr_init( &attr);
pthread_attr_getstacksize(&attr, &stacksize);
printf(“Default stack size - %li\n”, stacksize);
stacksize = sizeof(double) * N * N + MEGEXTRA;
pthread_attr_setstacksize (&attr, stacksize);
for(t=0;t < NUM_THREADS; t++) {
printf("Creating thread with stacksize - %li\n", stacksize);
rc = pthread_create(&threads[t], &attr, PrintHello, (void *)&t);
. . .
}
pthread_attr_destroy(&attr):
. . . 4-Threads 51
Thread Suspension and Termination
4-Threads 52
Thread Suspension and Termination
4-Threads 53
Joinable Threads
• Detached Thread
– On termination all thread resources are released by the OS
– A detached thread cannot be joined
– No way to get at the return value of the thread
• Joinable Thread
– On thread termination thread ID and exit status are saved by the OS
– Joining a thread means waiting for a thread with a certain ID
➢ One way to accomplish synchronization between threads
4-Threads 54
Joinable Threads
• Threads which have exited but have not been joined are equivalent
to zombie processes
– Their resources cannot be fully recovered
4-Threads 55
Joinable Threads: Example
#include <stdio.h>
#include <pthread.h> /* Set threads properties */
pthread_attr_init(&attr);
int x = 5; pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_JOINABLE);
int child_code()
/* Create new thread */
{
rc = pthread_create(&child_thread,
while (x>0){ &attr, (void*) &child_code, NULL);
x=x-1; /* Free attributes object */
printf("x has changed to %d\” pthread_attr_destroy(&attr);
,x);
} /* concurrent computation */
return 0; x=x+5;
} printf("x has change to %d\n",x);
int main(int argc, char *argv[])
/*wait for thread to terminate */
{
pthread_join(child_thread, status);
int rc;
pthread_exit(NULL);
void** status=0;
}
pthread_t child_thread;
pthread_attr_t attr;
4-Threads 56
Possible Outcome
No deterministic execution!
• Two threads can interleave in multiple ways
• Requires further synchronization
Child: x=5
while (x>0){
x=x-1; • x has changed to 4
printf("x has changed to %d \n",x); • x has changed to 3
}
4-Threads 57
Joinable Threads: Example
#include <pthread.h> /* Initialize & set thread attribute
#define NUM_THREADS 4 */ pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,
void *BusyWork(void *t){ PTHREAD_CREATE_JOINABLE);
long tid = (long)t; for(t=0; t<NUM_THREADS; t++) {
double result=0.0; printf("Main:creating thread %ld\n", t);
printf("Thread %ld starting...\n",tid); pthread_create(&thread[t], &attr,
for (int i=0; i<1000000; i++){ BusyWork, (void *)t);
result = result + sin(i) * }
tan(i); /* Free attribute & wait for threads */
} pthread_attr_destroy(&attr);
printf("Thread %ld done. for(t=0; t<NUM_THREADS; t++) {
Result = %e\n",tid, result); pthread_join(thread[t], &status);
pthread_exit((void*) t); printf("Main: completed join with thread
} %ld with status %ld\n", t,
int main (int argc, char *argv[]) { (long)status);
pthread_t thread[NUM_THREADS]; }
pthread_attr_t attr; printf("Main: program completed. \n");
int rc; pthread_exit(NULL);
long *status;
void t; }
4-Threads 58
Possible Output
Main: creating thread 0
Main: creating thread 1
Thread 0 starting...
Main: creating thread 2
Thread 1 starting...
Main: creating thread 3
Thread 2 starting...
Thread 3 starting...
Thread 1 done. Result = -3.153838e+06
Thread 0 done. Result = -3.153838e+06
Main: completed join with thread 0 with status of 0
Main: completed join with thread 1 with status of 1
Thread 3 done. Result = -3.153838e+06
Thread 2 done. Result = -3.153838e+06
Main: completed join with thread 2 with status of 2
Main: completed join with thread 3 with status of 3
Main: program completed. Exiting.
4-Threads 59
Making a Thread Detached
4-Threads 61