OPERATING SYSTEMS
Chapter 4 – Threads
CS3104-Operating Systems
Syed Sherjeel Ahmad Gilani, Fall 2019
Threads
Overview
Multithreading Models
Thread Libraries
Threading Issues
Operating System Examples
Windows XP Threads
Linux Threads
3
Objectives
To introduce the notion of a thread—a
fundamental unit of CPU utilization that forms
the basis of multithreaded computer systems.
To discuss the APIs for the Pthreads, Win32,
and Java thread libraries.
To examine issues related to multithreaded
programming.
4
Motivation
Threads run within application
Multiple tasks within the application can be
implemented by separate threads
Update display
Fetch data
Spell checking
Answer network requests
Process creation is heavy-weight while thread
creation is light-weight
Can simplify code, increase efficiency
Kernels are generally multithreaded
5
Single and Multithreaded Processes
6
Multithreaded Server Architecture
7
Benefits – Multithreaded programming
Responsiveness
Interactive application can run even part is
blocked
Resource sharing
Share resources of the process they belong to
(by default)
Economy
Creating a thread and to context switch is
economical as compare to process
Scalability
Benefits of multithreading can be even greater
in a multiprocessor architecture
8
Multicore Programming
Multicore systems putting pressure on
programmers for performance
Challenges include:
Dividing activities
Balance
Data splitting
Data dependency
Testing and debugging
9
Concurrent Execution on Single-core System
Tasks 1, 2, 3 & 4
10
Parallel Execution on Multicore System
Tasks 1, 2, 3 & 4
11
User Threads
Thread management done by user-level
threads library
Three main thread libraries:
POSIX Pthreads
Win32 threads
Java threads
12
Kernel Threads
Supported by the Kernel
Examples
Windows XP/2000
Solaris
Linux
Tru64 UNIX
Mac OS X
13
Multithreading Models
Many-to-One
One-to-One
Many-to-Many
14
Many-to-One Model
Many user-level threads mapped to
single kernel thread
Examples:
Solaris Green Threads
GNU Portable Threads
15
One-to-One Model
Each user-level thread maps to kernel
thread
Examples
Windows NT/XP/2000
Linux
Solaris 9 and later
16
Many-to-Many Model
Allows many user level threads to be
mapped to many kernel threads
Allows the operating system to create a
sufficient number of kernel threads
Windows NT/2000 with ThreadFiber package
Solaris prior to version 9
17
Two-level Model
Similar to M-to-M, except that it allows a user
thread to be bound to kernel thread
Examples
Solaris 8 and earlier
IRIX
HP-UX
Tru64 UNIX
18
Thread Libraries
Thread library provides programmer with
API for creating and managing threads
Two primary ways of implementing
Library entirely in user space
Kernel-level library supported by the OS
19
Pthreads
May be provided either as user-level or kernel-
level
A POSIX standard (IEEE 1003.1c) API for
thread creation and synchronization
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)
20
Pthreads Example
21
Pthreads Example (Cont.)
22
Win32 API Multithreaded C Program
23
Win32 API Multithreaded C Program
(Cont.)
24
Java Threads
Java threads are managed by the JVM
Typically implemented using the threads
model provided by underlying OS
Java threads may be created by:
Extending Thread class
Implementing the Runnable interface
25
Java Threads
When we execute an application:
1. The JVM creates a Thread object whose task is
defined by the main() method
2. The JVM starts the thread
3. The thread executes the statements of the
program one by one
4. After executing all the statements, the method
returns and the thread dies
26
Java Thread
Each thread has its private run-time stack
If two threads execute the same method,
each will have its own copy of the local
variables the methods uses
However, all threads see the same
dynamic memory, i.e., heap (are there
variables on the heap?)
Two different threads can act on the same
object and same static fields concurrently
27
Creating Threads
There are two ways to create our own
Thread object
1. Subclassing the Thread class and instantiating
a new object of that class
2. Implementing the Runnable interface
In both cases the run() method should be
implemented
28
Extending Thread
public class ThreadExample extends Thread {
public void run () {
for (int i = 1; i <= 100; i++) {
System.out.println(“---”);
}
}
}
29
Thread Methods
void start()
Creates a new thread and makes it runnable
This method can be called only once
void run()
The new thread begins its life inside this method
void stop() (deprecated)
The thread is being terminated
30
Thread Methods
void yield()
Causes the currently executing thread object to
temporarily pause and allow other threads to
execute
Allow only threads of the same priority to run
void sleep(int m) or sleep(int m, int n)
The thread sleeps for m milliseconds, plus n
nanoseconds
31
Implementing Runnable
public class RunnableExample implements Runnable {
public void run () {
for (int i = 1; i <= 100; i++) {
System.out.println (“***”);
}
}
}
32
A Runnable Object
When running the Runnable object, a Thread
object is created from the Runnable object
The Thread object’s run() method calls the
Runnable object’s run() method
Allows threads to run inside any object,
regardless of inheritance
Example – an applet
that is also a thread
33
Starting the Threads
public class ThreadsStartExample {
public static void main (String argv[]) {
new ThreadExample ().start ();
new Thread(new RunnableExample ()).start ();
}
}
What will we see when running
ThreadsStartExample?
34
35
Scheduling Threads
start()
Ready queue
Newly created
threads
Currently executed
thread
I/O operation completes
•Waiting for I/O operation to be completed
•Waiting to be notified
•Sleeping
•Waiting to enter a synchronized section
36
Thread State Diagram
Alive
Running
new ThreadExample(); while (…) { … }
New Thread Runnable Dead Thread
thread.start();
run() method returns
Blocked
Object.wait()
Thread.sleep()
blocking IO call
waiting on a monitor
37
Example
public class PrintThread1 extends Thread {
String name;
public PrintThread1(String name) {
this.name = name;
}
public void run() {
for (int i=1; i<100 ; i++) {
try {
sleep((long)(Math.random() * 100));
} catch (InterruptedException ie) { }
System.out.print(name);
}
}
38
Example (cont)
public static void main(String args[]) {
PrintThread1 a = new PrintThread1("*");
PrintThread1 b = new PrintThread1("-");
a.start();
b.start();
}
}
39
40
Example 2
Create 2 threads from the Main, then start
them
Threads will be instances of the same
thread sub-class
Use argument of constructor of new thread
class to pass text name of thread, e.g.,
“thread1” and “thread2”
Data member provides different data per
thread (i.e., then name)
A data member can also be used to share data
41
class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
public void run() {
for (;;) {
System.out.println(name + ": hello world");
}
}
}
public class Main2 {
public static void main(String [] args) {
MyThread t1 = new MyThread("thread1");
MyThread t2 = new MyThread("thread2");
t1.start(); t2.start();
}
}
42
thread2: hello world
thread2: hello world
thread2: hello world Some Output
thread2: hello world
thread2: hello world
thread2: hello world
thread2: hello world
thread2: hello world
thread2: hello world
thread2: hello world
thread2: hello world See the variation in
thread2: hello world output: This variation
thread2: hello world
in output is called a
thread2: hello world
thread2: hello world “race condition” (often
thread1: hello world race conditions are
thread2: hello world bugs in programs)
thread1: hello world
thread2: hello world
thread2: hello world
thread1: hello world
thread2: hello world
43
thread2: hello world
java.lang.Thread
public static void yield();
Method of java.lang.Thread
Thread gives up CPU for other threads ready to
run
44
class MyThread extends Thread {
private String name;
public MyThread(String name) {
this.name = name;
}
public void run() {
for (;;) {
System.out.println(name + ": hello world");
yield();
}
}
}
public class Main3 {
public static void main(String [] args) {
MyThread t1 = new MyThread("thread1");
MyThread t2 = new MyThread("thread2");
t1.start(); t2.start();
}
} 45
thread1: hello world
thread2: hello world
thread1:
thread2:
hello
hello
world
world
Some Output
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world
thread2: hello world
thread1: hello world Notice the alternation
thread2: hello world of output
thread1: hello world
thread2:
46 hello world
thread1: hello world
More Thread Members: join
public final void join();
MyThread t1 = new MyThread("thread1");
t1.start();
t1.join();
Wait until the thread is “not alive”
Threads that have completed are “not alive”
as are threads that have not yet been started
47
Threading Issues
Semantics of fork() and exec() system calls
Thread cancellation of target thread
Asynchronous or deferred
Signal handling
Synchronous and asynchronous
Thread pools
Thread-specific data
Create Facility needed for data private to thread
Scheduler activations
48
Semantics of fork() and exec()
Unix has two versions of fork()
One that duplicates all threads
Other duplicates only the thread that called the
fork()
What will happen if a thread calls the exec()
function?
The program specified in exec() parameters will
replace the entire process, including all threads
49
Thread Cancellation
Terminating a thread before it has finished
(Target Thread)
Two general approaches:
Asynchronous cancellation terminates the
target thread immediately
Deferred cancellation allows the target thread
to periodically check if it should be cancelled
50
Signal Handling
Signals are used in UNIX systems to notify a
process that a particular event has occurred
A signal handler is used to process signals
1. Signal is generated by particular event
2. Signal is delivered to a process
3. Signal handler routine handles the signal
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
51
Signal Handling in Unix
Standard Unix function for delivering signals is:
Kill(pid_t pid, int signal)
For threads, POSIX Pthread function is:
Pthread_kill(pthread_t tid, int signal)
Most Unix versions allow a thread to specify
which signals it will accept and which it will block
Typically a signal is delivered to the first thread
that is not blocking it
52
Thread Pools
Create a number of threads in a pool where
they await work
Advantages:
Usually slightly faster to service a request with an
existing thread than creating a new thread
Allows the number of threads in the application(s)
to be bound to the size of the pool
53
Thread Specific Data
Allows each thread to have its own copy of
data
Useful when you do not have control over the
thread creation process (i.e., when using a
thread pool)
54
Scheduler Activations
Communication between kernel and thread library
is required e.g. many-to-many thread model
Helps to maintain the appropriate number of
kernel threads allocated to the application
Scheduler activations provide upcalls - a
communication mechanism from the kernel to the
thread library
This communication allows an application to
maintain the correct number of kernel threads
55
Lightweight Processes (LWP)
An intermediate data
structure is maintained
between user and kernel
thread
User threads are scheduled
on LWP that appears as a
virtual processor to
application
Each LWP is attached to a
kernel thread
56
Operating System Examples
Windows XP Threads
Linux Thread
57
Windows XP Threads
Implements the one-to-one mapping, kernel-level
Each thread contains
A thread id
Register set
Separate user and kernel stacks
Private data storage area
The register set, stacks, and private storage area
are known as the context of the threads
The primary data structures of a thread include:
ETHREAD (executive thread block)
KTHREAD (kernel thread block)
TEB (thread environment block)
58
Windows XP Threads Data Structures
59
Linux Threads
Linux refers to them as tasks rather than threads
Thread creation is done through clone() system
call
clone() allows a child task to share the address
space of the parent task (process)
struct task_struct points to process data
structures (shared or unique)
60
References
Operating Systems Concepts, Silberschatz et
al.
www.cs.huji.ac.il/course/2003/dbi/2003/Lectur
es/ppt/threads.ppt (The Hebrew University of Jerusalem)
www2.mta.ac.il/~amirk/java/presentations/04
-Threads.ppt
(The Academic College of Tel Aviv)
61