Chapter - 4 Threads (Full)
Chapter - 4 Threads (Full)
Threads
1
Outline and Objectives
Objectives
Outline
• Overview
To introduce the notion of a thread — a fundamental unit of CPU utilization that
• forms the basisModels
Multithreading of multithreaded computer systems
•• To discuss
Thread the APIs for the Pthreads, Win32, and Java thread libraries
Libraries
•• To examineIssues
Threading issues related to multithreaded programming
• Operating System Examples
• Windows XP Threads
• Linux Threads
• Re-entrancy
• Thread specific data
2
Threading Concept
3
Threads and Thread Usage
4
5
6
Benefits of using threads for an App
• Responsiveness
– One thread blocks, another one runs.
– One thread may always wait for the user
• Resource Sharing
– Threads can easily share resources
• Economy
– Creating a thread is fast
– Context switching among threads may be faster
• Scalability
– Multiprocessors can be utilized better
7
Threads and Thread Usage
data data
CPU
blocks blocks
blocks
run enough
8
a multithreaded process’ execution flows:
threads
Instructions of the Program
main()
Thread0
Thread2
Thread1
time
9
Multithreading Concept
CPU
10
Multithreading Concept
Process Process
Schedulable Entities
We can select one of them and run
11
Multithreading Concept
thread1 thread2 thread3 thread4
function1(…)
{
….
{
function2(…)
{
….
{
main()
{ ….
thread_create (function1 ,…);
….
thread_create (function2, …);
….
thread_create (function1, …);
….
}
12
Single and Multithreaded Processes
13
Multicore programming and multithreading
challenges
• Multicore systems putting pressure on programmers.
– Threading can utilize Multicore systems better, but it has some challenges
• Threading Challenges include
– Dividing activities
• Come up with concurrent tasks
– Balance
• Tasks should be similar importance and load
– Data splitting
• Data may need to be split as well
– Data dependency
• Data dependencies should be considered; need synchronization of
activities
– Testing and debugging
• Debugging is more difficult
14
Multithreaded Server Architecture
15
Concurrent Execution on a Single-core System
16
Parallel Execution on a Multicore System
17
Speedup: Amdahl’s Law
18
Threading Support
19
Threading Support
20
Multithreading Models
• Finally a relationship must exist between user threads and kernel thread(s)
– Mapping user level threads to kernel level threads
21
Many-to-One Model:
Implementing Threads in User Space
• Many user-level threads
mapped to a single kernel thread
• Examples:
– Solaris Green Threads
– GNU Portable Threads
• Thread management
done at user space, by a
thread library
23
One-to-One Model:
Implementing Threads in Kernel Space
• Kernel may implement threading and can manage threads, schedule threads.
Kernel is aware of threads.
24
One-to-One Model:
Implementing Threads in Kernel Space
• Provides more concurrency; when a
thread blocks, another can run.
Process A Process B
Blocking system calls are not problem
anymore. (+)
• Multiple processors can be utilized as
well. (+).
• Kernel can stop a long running thread
and run another thread. No need for
explicit request from a thread to be
stopped. (+)
• PCB A
Need system calls to create threads
PCB B
and this takes time; (-) process table
Kernel
• thread switching costly; (-)
• any thread function requires a system
Thread table
call. (-)
25
Threading API
26
Thread Libraries
27
Pthreads Library
28
Pthreads Example
• The program will just create a new thread to do a simple computation: will sum
all integers upto a given parameter value
– sum = 1+2+…+parameter_value N
sum i
i 1
• The main thread will wait until sum is computed into a global variable.
29
Pthreads Example
#include <pthread.h>
#include <stdio.h>
30
Pthreads Example
int main(int argc, char *argv[]){
pthread_t tid; /* id of the created thread */
pthread_attr_t attr; /* set of thread attributes */
if (argc != 2) {
fprintf (stderr, “usage: a.out <value>\n”);
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf (stderr, “%d must be >= 0\n”, atoi(argv[1]);
return -1;
}
pthread_attr_init (&attr);
pthread_create (&tid, &attr, runner, argv[1]);
pthread_join (tid, NULL);
printf (“sum = %d\n”, sum);
}
31
Pthreads Example
int upper;
upper = atoi(param);
sum = 0;
pthread_exit(0);
}
32
Pthreads Example
int main(…) thread1 thread2
{
…
….
pthread_create(&tid,…,runner,..);
wait
pthread_join(tid);
runner (…)
{
….
sum = …
pthread_exit();
{
33
Compiling and running the program
• You can put the above code into a .c file, say mysum.c
• In order to use the Pthreads functions, we need to include pthread.h header
file in our program (as shown in previous slides)
• We also need to link with the pthread library (the Pthreads API functions are
not implemented in the standard C library). The way to do that is using the –l
option of the C compiler. After -l you can provide a library name like pthread.
34
Windows Threads
35
Java Threads
36
From Single-threaded to Multithreaded
• Scope of variables:
– Normally we have: global, local
– With threads, we want: global, local, and thread-specific (thread
wide)
37
Thread Specific Data
(Thread Local Storage: TLS)
• Allows each thread to have its own copy of data
– Each thread refers to the data with the same name.
• Example:
– Each thread can do:
• create_global (bufptr); // create a name (i.e., key)
• allocate space for a buffer // create block of memory
– buf = malloc (BUFFERSIZE)
• set_global (bufptr, buf); // associate the pointer
• buf = (char *) get_global (bufptr); // get the pointer to access
• use pointer to buffer to access data in the buffer
– Here bufptr is the same name of the variable used in each thread.
But each thread has its own copy of data.
38
Thread Specific Data
(Thread Local Storage: TLS)
Thread 1 Thread 2 Thread 3
Each thread is using the same variable name bufptr to get access to its own
specific data.
39
Thread Specific Data
Example:
pthread_key_t data1;
pthread_key_create (&data1, …);
41
From Singlethread to Multithreaded
int status; // a global variable
func1(…) {
….
status = …
do_something_based_on(status);
This is a
}
single threaded
program
func2(…) {
…
status = …
do_something_based_on(status);
}
main() {
….
func1 (…);
func2 (…);
}
42
From Singlethread to Multithreaded
int status=60; • We can have problem here.
func1(…) {
…. • Just after func1 of thread 1
status = 40… updated status, a thread
do_something_based_on(status); switch may occur and 2nd
malloc thread can run and update
} status.
44
Examples from Operating Systems
45
Operating System Examples
• Windows XP Threads
• Linux Threads
46
Linux Threads
• clone() allows a child task to share the address space of the parent
task (process)
47
Clone() and fork()
user program
sys_fork() sys_clone(){
{ ….
… }
kernel }
48
References
• The slides here are adapted/modified from the textbook and its slides:
Operating System Concepts, Silberschatz et al., 7th & 8th editions,
Wiley.
• Operating System Concepts, 7th and 8th editions, Silberschatz et al.
Wiley.
• Modern Operating Systems, Andrew S. Tanenbaum, 3rd edition, 2009.
49
Additional Study Material
50
Many-to-Many Model & Two-level Model
Two-level Model
Many-to-Many Model
• Similar
Allows many
to M:M,user
except
levelthat
threads
it allows
to bea mapped
user thread
to many
to bekernel
boundthreads
to a kernel
• thread
Allows the operating system to create a sufficient number of kernel threads
• Examples
Solaris prior to version 9
– IRIX NT/2000 with the ThreadFiber package
• Windows
– HP-UX
– Tru64 UNIX
– Solaris 8 and earlier
51
Implicit Threading
52
Implicit Threading
53
Thread Pools
• Advantages:
– Faster
54
OpenMP
Number of threads ==
Number of cores
55
Grand Central Dispatch (GCD)
56
Other Threading Issues
57
Threading Issues
58
Semantics of fork() and exec()
59
Thread Cancellation
60
Thread Cancellation
pthread_t tid;
while (1) {
/* do some work */
…
Target thread /* check if there is cancel request */
} pthread_test_cancel();
61
Signal Handling
62
Signal Handling
• a Signal:
1. Signal is generated by a particular event
2. Signal is delivered to a process (same or different process)
3. Signal is handled
63
Signal Handling
• Options:
– Deliver the signal to the thread to which the signal applies
– Deliver the signal to every thread in the process
– Deliver the signal to certain threads in the process
– Assign a specific thread to receive all signals for the process
64
a C program using signals
#include <stdio.h> • While a program is running, if
#include <signal.h> we press CTRL-C keys, the
#include <stdlib.h> program will be terminated
(killed). We are sending a
SIGINT signal to the program
static void sig_int_handler() {
printf("I received SIGINT signal. bye... \n"); • By default, SIGINT is handled
fflush(stdout); by kernel. By default, kernel
exit(0); terminates the program.
}
• But if we specify a handler
function as here, then our
int main() { program can handle it.
signal (SIGINT, sig_int_handler);
• Kernel will notify our process
while (1) with a signal when user presses
; the CTRL-C keys.
}
Program X
65
delivering signal (notifying)
CTRL-C
Keyboard
66
kill program
process id = 3405
Keyboard
67
Some Signals
SIGHUP Hangup.
SIGILL Illegal instruction.
SIGINT Terminal interrupt signal.
• Kernel threads are good, but they are slower if we create short threads
too frequently, or threads wait for each other too frequently.
• Goal is mimic kernel threads at user level with some more kernel
support. But kernel will not create another thread for each user thread
(M:1 or M:M model).
69
Scheduler Activations: Upcall mechanism
Process
Run-time
System upcall handler
(i.e. thread library) Thread schedules
table another thread
library registers a handler makes system call
(upcall handler)
when kernel runs the upcall handler
process/thread (i.e. makes an upcall; activates
is started Kernel the user level scheduler)
kernel detects that I/O is finished
Kernel initiates I/O
and blocks the thread kernel informs the library via upcall
70
Windows XP Threads
71
Windows XP Threads
72