Deccansoft Software Services - [Link] 4.
5 Multithreading
Agenda
1. Threading Overview
2. Scheduling
3. Thread states
4. Programming Threads
5. Methods of Thread class
6. Thread Pool
7. Thread Synchronization
Monitor
Mutex
Semaphore
Events
8. Parallel Programming using Task Parallel Library
9. Asynchronous Programming using async and wait Keywords
1
Deccansoft Software Services - [Link] 4.5 Multithreading
Overview of Process and Threads
Process:
A process is a running instance of an application.
Every process has its own memory address space (execution environment) and it is in that all the data and the
instructions of that process reside.
A process has a self-contained execution environment. A process generally has a complete, private set of basic
run-time resources; in particular, each process has its own memory space
Thread:
The path of execution of instructions within a process is called a thread.
It has a starting point, execution sequence and terminating point.
A program with multiple simultaneous paths of execution is said to be multithreaded application.
Multithreading Multiprocessing/Multitasking
Multithreading is the ability of an operating system to Multitasking is the ability of an operating system to
execute the different parts of the program, called accommodate more than one program in the memory at
threads, concurrently. the same time.
In multithreading all threads share same process Processes do not share the memory
address space [memory].
Threads can share variables since threads are in same External resources like file system or database must be
process. used for communication between multiple processes and
each one runs under its unique process address space.
Inter thread communication is simple Inter process communication is complex
Less resources required to launch/run them since they CPU has to spend more resources for launching a new
are part of an already running process, hence they are process hence process is known as heavy weight.
called as light weight tasks.
Types of Scheduling
Preemptive: OS can un-schedule a thread even if it is not completed its task.
Non-Preemptive: OS cannot unschedule the thread. A Thread should either get unscheduled itself or it should
complete its task and release the processor.
Scheduling is done based on the priority of the thread. A thread with highest priority is executed in the
processor. If multiple threads exist with same priority then a time slice is assigned to each thread.
In MS-Windows execution of the thread is based on: Preemptive Scheduling Priority Time slice
Also, in all versions of MS Windows, to avoid starvation low priority threads are also executed in the processor
but the number of times they execute is very less.
Switching means that the processor stores the state of the outgoing thread (it does so by noting the current
processor register values and the last instruction-set the thread was about to perform), restores the state of the
2
Deccansoft Software Services - [Link] 4.5 Multithreading
incoming thread (again by restoring its processor register values and picking the last instruction-set where it had
left itself) and then runs it.
Note: On a multi-processor system, the operating system can allocate individual threads to the separate processors,
which thus fastens the execution of the program. The efficiency of the threads also increases significantly because
the distribution of the threads on several processors is faster than sharing time-slices on a single processor. It is
particularly useful to have a multi-processor system for 3D modeling and image-processing.
Example of some Multithreading Applications:
1. MS-Word – Auto Saving, Spell Checking, Printing while editing
2. [Link] – Intellisense, Auto Compilation.
3. Browser – Downloading multiple files and browsing simultaneously.
4. Media Player – Movie and Sound
Thread State Diagram
1. Running: A thread is said to be in running state when it is in processor executing one of its instruction.
2. Ready: Thread is waiting for processor to be allocated to it. This is the only entry point to running state. When
the thread is unscheduled it returns from running to ready state.
3. Dead: After the execution of all the instructions in the thread it goes to dead state. Dead threads cannot be
revived.
4. Sleeping: While sleeping the thread doesn’t perform any task. A thread goes to sleeping state by itself and for a
predefined time. A sleeping thread when interrupted throws “ThreadInterruptedException”. All the
resources/locks that the thread is holding are blocked when a thread is in sleeping state.
5. Suspended: A thread can suspend itself or by another thread. The suspended thread cannot resume by itself. A
thread can go to suspended state for an indefinite time.
6. Blocked: A thread is said to be in blocked state when the resources are not available to it and it is waiting for
them. The thread automatically resumes once the resource is made available.
7. Waiting: The thread before it goes to waiting state releases its resources / locks it has blocked. A waiting thread
has to be pulsed by another thread only then it can resume and goes to ready state.
3
Deccansoft Software Services - [Link] 4.5 Multithreading
In .Net every thread has two objects associated with it.
An Object of type [Link] and it is responsible for managing the lifetime and the states of
the thread.
A custom object, it is responsible for providing the instructions and data which the thread has to manage
during its lifetime.
Example 1
Public Class Demo
Public Dim Message As String
Public Dim Interval As Integer = 1000
Public Sub Run()
Dim i As Integer
For i = 1 To 10
[Link]([Link] & " : " + Message)
Next
End Sub
End Class
Public Class Program
Shared Sub Main(ByVal args As String())
[Link]("Main method begins")
Dim d As New Demo
Dim t As New Thread(New ThreadStart(AddressOf [Link]))
[Link] = "T"
[Link] = "Hi"
[Link] = 1000
[Link]()
Dim d1 As New Demo()
Dim t1 As New Thread(New ThreadStart(AddressOf [Link]))
[Link] = "T1"
[Link] = "Hello"
[Link] = 2000
[Link]()
[Link]()
If [Link] Then
[Link]("T is Alive")
End If
[Link]()
[Link]("Main method ends")
End Sub
End Class
4
Deccansoft Software Services - [Link] 4.5 Multithreading
Code: 14.1 VB
Example 1
class Demo
{
public string Message;
public int Interval = 1000;
public void Run()
{
for (int i = 0; i < 5; i++) //while(true)
{
[Link]([Link] + " : " + Message);
[Link](Interval);
}
}
}
class Program
{
static void Main(string[] args)
{
[Link]("Main method begins");
Demo d = new Demo();
Thread t = new Thread(new ThreadStart([Link]));
[Link] = "T";
[Link] = "Hi";
[Link] = 1000;
[Link]();
Demo d1 = new Demo();
Thread t1 = new Thread(new ThreadStart([Link]));
[Link] = "T1";
[Link] = "Hello";
[Link] = 2000;
[Link]();
[Link](2000);
if ([Link])
[Link]("t is alive");
[Link]();
//[Link] = [Link] = true;
[Link]("Main method ends");
}
5
Deccansoft Software Services - [Link] 4.5 Multithreading
Code: 14.1 C#
Demo class encapsulates the instructions of thread in Run method and also encapsulates data in Message and
Interval data members.
Important Points:
The process terminates when the main thread terminates.
A thread terminates only when the other non-background threads which it has created terminates.
The creator doesn’t wait for the background thread if it has to terminate.
Some Important Methods of Thread class
Join(): If a thread executes [Link]() the current thread state is changed to waiting and it remains in that state
until the thread referred by “t” is terminated.
Join(3000): The current threads waits for a max of 3000 milliseconds and then would resume automatically.
IsAlive() : To check if the thread is dead or alive.
[Link] : To Get the reference of the current thread.
[Link] = [Link].
Abort(): To stop the thread. When the Abort() method is called on a thread it throws ThreadAbortException
irrespective of its state. If this exception is unhandled the thread terminates, and if it is handled and if
[Link]() is executed the thread is not aborted and would continue normal execution.
IsBackground: When a thread is created as background thread, the creator thread does not wait for the
background thread to terminate or join the creator thread. The background thread is automatically aborted
when the creator thread aborts.
Example 2: Program to Print “Data” at a regular interval and also facility to change that data by reading its value from
keyboard.
Example 2
Public Class PrintThread
Public Data As String
Public Sub Run()
While True
[Link](Data)
[Link](1000)
End While
End Sub
End Class
Public Class PrintProgram
6
Deccansoft Software Services - [Link] 4.5 Multithreading
Shared Sub Main()
Dim p As New PrintThread()
Dim t As New Thread(New ThreadStart(AddressOf [Link]))
[Link]()
While True
[Link]("Please Enter the Data: ")
[Link] = [Link]()
End While
End Sub
End Class
Code: 14.2 VB
Example 2
class PrintThread
{
public string Data;
public void Run()
{
while (true)
{
[Link](Data);
[Link](1000);
}
}
}
class PrintProgram
{
public static void Main()
{
PrintThread p = new PrintThread();
Thread t = new Thread(new ThreadStart([Link]));
[Link]();
while (true)
{
[Link]("Please enter the data: ");
[Link] = [Link]();
}
}
}
7
Deccansoft Software Services - [Link] 4.5 Multithreading
Code: 14.2 C#
Example 3: To Demonstrate the Priority of Thread.
In windows OS for every cycle of high priority thread scheduled in the processor, the priority of low priority thread is
boosted by one unit. This is done so that even those threads whose priority is low are given a chance to execute in
the processor to avoid starvation.
Example 3
Public Class Hello
Public Counter As Long
Public Sub Run()
While True
Counter = Counter + 1
End While
End Sub
End Class
Public Class PriorityProgram
Shared Sub Main()
Dim h1 As New Hello()
Dim t1 As New Thread(New ThreadStart(AddressOf [Link]))
Dim h2 As New Hello()
Dim t2 As New Thread(New ThreadStart(AddressOf [Link]))
[Link] = [Link]
[Link] = [Link]
[Link] = [Link]
[Link]()
[Link]()
[Link](2000)
[Link]()
[Link]()
Dim perT1 As Double = 100.0 * [Link] / ([Link] + [Link])
Dim perT2 As Double = 100.0 * [Link] / ([Link] + [Link])
[Link]("T1" + perT1)
[Link]("T2" + perT2)
End Sub
End Class
Code: 14.3 VB
Example 3
8
Deccansoft Software Services - [Link] 4.5 Multithreading
class Hello
{
public long Counter;
public void Run()
{
while (true)
Counter++;
}
}
class PriorityProgram
{
static void Main(string[] args)
{
Hello h1 = new Hello();
Thread t1 = new Thread(new ThreadStart([Link]));
Hello h2 = new Hello();
Thread t2 = new Thread(new ThreadStart([Link]));
[Link] = [Link];
[Link] = [Link];
[Link] = [Link];
[Link](); [Link]();
[Link](2000);
[Link](); [Link]();
double perT1 = 100.0 * [Link] / ([Link] + [Link]);
double perT2 = 100.0 * [Link] / ([Link] + [Link]);
[Link]("T1 " + perT1);
[Link]("T2 " + perT2);
}
}
Code: 14.3 C#
Note:
On Dual Core processor machine, this program should be executed with three threads because the
processor would execute two threads at the same time irrespective of their priority.
9
Deccansoft Software Services - [Link] 4.5 Multithreading
Example: To Demonstrate Suspend-Resume / Sleep – Interrupt / Abort Demo and CROSS Thread Operation.
Example 4
Private Sub Run()
Dim n As Integer = 0
While True
Try
n=n+1
[Link] = [Link]()
[Link](1000)
Catch e As ThreadAbortException
Dim dlgResult As DialogResult = [Link]("Are you sure?", "Abort",
[Link])
If (dlgResult = [Link]) Then
[Link]()
End If
Catch e As ThreadInterruptedException
n=0
End Try
End While
End Sub
Dim t As Thread
Private Sub btnStart_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
t = New Thread(New ThreadStart(AddressOf Run))
[Link] = True
[Link]()
End Sub
Private Sub btnAbort_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
[Link]()
End Sub
10
Deccansoft Software Services - [Link] 4.5 Multithreading
Private Sub btnSuspend_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
[Link]()
End Sub
Private Sub btnResume_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
[Link]()
End Sub
Private Sub btnInterrupt_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
[Link]()
End Sub
Private Sub btnThreadState_Click(ByVal sender As [Link], ByVal e As [Link]) Handles
[Link]
[Link]([Link])
End Sub
Shared Sub Main()
[Link](New DemoForm())
End Sub
Code: 14.4 VB
Example 4
private void Run()
{
int n = 0;
while (true)
{
try
{
n++;
[Link] = [Link]();
[Link](1000);
}
catch (ThreadAbortException e)
{
DialogResult dlgResult;
dlgResult = [Link]("Are you sure?",
"Abort", [Link]);
if (dlgResult == [Link])
11
Deccansoft Software Services - [Link] 4.5 Multithreading
[Link]();
}
catch (ThreadInterruptedException e)
{
n = 0;
}
}
}
Thread t;
private void btnStart_Click(object sender, EventArgs e)
{
t = new Thread(new ThreadStart(Run));
[Link] = true;
[Link]();
}
private void btnAbort_Click(object sender, EventArgs e)
{
[Link]();
}
private void btnSuspend_Click(object sender, EventArgs e)
{
[Link]();
}
private void btnResume_Click(object sender, EventArgs e)
{
[Link]();
}
private void btnInterrupt_Click(object sender, EventArgs e)
{
[Link]();
}
private void btnThreadState_Click(object sender, EventArgs e)
{
[Link]([Link]());
}
public static void Main()
{
[Link](new DemoForm());
}
12
Deccansoft Software Services - [Link] 4.5 Multithreading
Code: 14.4 C#
Dealing with Cross Thread Operations for Controls.
Problem: If the following Exception is throw:
“Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on”
Solution:
[Link](new MethodInvoker(delegate
{
[Link] = "Demo";
}));
Thread Pool
A thread pool is a collection of threads that can be used to perform a number of tasks in the background.
Thread pools are often employed in server applications. Each incoming request is assigned to a thread from the
thread pool, so the request can be processed asynchronously, without tying up the primary thread or delaying
the processing of subsequent requests.
Once a thread in the pool completes its task, it is returned to a queue of waiting threads, where it can be reused.
This reuse enables applications to avoid the cost of creating a new thread for each task
Thread pools typically have a maximum number of threads. If all the threads are busy, additional tasks are
placed in queue until they can be serviced as threads become available.
public static void Run(object state)
{
[Link]([Link]() + " : " + state);
[Link](1000);
}
static void Main(string[] args)
{
[Link](2,2);
[Link](4, 4);
WaitCallback wcb = new WaitCallback(Run);
for (int i = 0; i < 10; i++) {
[Link](wcb, i);
}
[Link](10000);
}
13
Deccansoft Software Services - [Link] 4.5 Multithreading
Thread Synchronization
Requirement: In situation where one object is shared by more than one thread, if the thread has to modify the state
of the object it should ensure that only one thread does so at a given instance of time.
Critical Section is a block of code which can be executed by only one thread at any given instance of time.
If there are two threads executing on same shared object then both the threads can execute some method on the
object at the same point of time and if they then change the state of the object, it may result in ambiguity of data
causing Threads De-Synchronization. To avoid this we use lock block.
In C# In VB Every object in .NET has a special type of resource called as Monitor. A
lock(ob) SyncLock (ob) thread trying to enter the lock block would have to acquire the monitor of
{ the specified object and only if it can do so it would be executing the locked
} End SyncLock block otherwise it will have to wait for the monitor.
Example 5
Public Class Shares
Public n As Integer
Public Function Incr() As Integer
SyncLock CurrentSection
n=n+1
Dim k As Integer = 0
For i = 1 To 100000000
k=k+1
Next
End SyncLock
End Function
End Class
Public Class Demo
Dim s As Shares
Public Sub New(ByVal s As Shares)
Me.s = s
End Sub
Public Sub Run()
[Link]([Link]())
End Sub
End Class
14
Deccansoft Software Services - [Link] 4.5 Multithreading
Public Class SyncDemo
Shared Sub Main()
Dim s As New Shares()
Dim d1 As New Demo(s)
Dim d2 As New Demo(s)
Dim t1 As New Thread(New ThreadStart(AddressOf [Link]))
Dim t2 As New Thread(New ThreadStart(AddressOf [Link]))
[Link]()
[Link]()
End Sub
End Class
Code: 14.5 VB
Example 5
class Shared
{
int n;
public int Incr()
{
lock (this)
{
n++;
int k = 0;
for (long i = 0; i < 100000000; i++)
k++;
return n;
}
}
}
class Demo
{
Shared s;
public Demo(Shared s)
{
this.s = s;
}
public void Run()
{
//lock (s) //To be used if the [Link] is not coded
15
Deccansoft Software Services - [Link] 4.5 Multithreading
//{ for Thread Safety (not having lock block)
[Link]([Link]());
//}
}
}
class SyncDemo
{
public static void Main()
{
Shared s = new Shared();
Demo d1 = new Demo(s);
Demo d2 = new Demo(s);
Thread t1 = new Thread(new ThreadStart([Link]));
Thread t2 = new Thread(new ThreadStart([Link]));
[Link](); [Link]();
}
}
Code: 14.5 C#
Thread safe class: A class whose objects state is not desynchronized when it is being used by more than one thread
at the same time.
Even if the class is not thread safe (methods changing the state of the object do not have code inside lock block)
we can still make use its functionality in multithreaded environment by calling all its method within a lock block
on the same object.
If a thread has acquired a monitor of an object, it can enter any number of lock blocks in different methods of
same object.
Locking degrades throughput i.e. the rate at which the output is generated.
Static members of a class can synchronize the code in them by acquiring the lock on Type instance of that class
16
Deccansoft Software Services - [Link] 4.5 Multithreading
M u tex
It is a synchronization resource managed by the OS. Thus it can be used for synchronizing threads running in
different processes.
Note: Monitor is a .Net specific object and is local to a given process and thus it cannot be used for synchronizing
threads running in different processes
If two or more threads have to be synchronized using Mutex, then either they should all refer to the same Mutex
object or if the objects are different then all the Mutex objects must have same name so that all the mutex objects
refers to the same mutex resource in the OS.
WaitOne(): Check for the availability of mutex. If available acquires it and would continue execution other
the current thread state is changed to waiting for mutex.
ReleseMutex(): – Releases the mutex
Mutex m = new Mutex(false, "test");
If the first parameter is true, the first thread creating the mutex object will be the owner of the mutex. False will
prevent the thread object to acquire the mutex till WaitOne() method is executed.
"test" is the name of the mutex as identified in OS.
Example 1:
class SharedForMutex
{
private int N;
//Mutex m = new Mutex();
public int Incr()
{
Mutex m = new Mutex(false, "M12345");
try
{
[Link]();
N++;
int k = 0;
for (int i = 0; i < 50; i++)
{
k++;
[Link](i);
[Link](300);
}
return N;
}
finally
{
[Link]();
}
}
}
class SharingThread1
{
17
Deccansoft Software Services - [Link] 4.5 Multithreading
public SharedForMutex shared;
public void Run()
{
int n = [Link]();
[Link](n);
}
}
class MutexDemo
{
static void Main(string[] args)
{
SharedForMutex s = new SharedForMutex();
SharingThread1 st1 = new SharingThread1() { shared = s };
SharingThread1 st2 = new SharingThread1() { shared = s };
Thread t1 = new Thread([Link]);
Thread t2 = new Thread([Link]);
[Link]();
[Link]();
}
}
Example2: To allow only once instance of the application to Run:
static void Main(string[] args)
{
Mutex m = new Mutex(false, "aslkfjaskfjklasjfklasjklfjasklfjasklfjasklfjlasfjlaskfjlaskfjkladsfjaskfkasflaskf");
bool acquired = [Link](0);
if (acquired)
{
[Link](new OnlyOneInstanceForm());
[Link]();
}
else
{
[Link]("Sorry, another instance of this application is already running");
}
}
Semaphore
Semaphore is used for synchronizing threads (within same process or in different process) and it works exactly like
Mutex but has a facility to allow more than one thread (but a pre-defined count) to execute a given block at the
same time.
Mutex can be treated as a special case of semaphore where count = 1.
Semaphore Example
Public Class Demo1
'static Semaphore s = new Semaphore(3,3);
Dim s As New Semaphore(3, 3, "Test")
Public Sub Run()
[Link]([Link] & " Started")
[Link]()
[Link](1000)
18
Deccansoft Software Services - [Link] 4.5 Multithreading
[Link]()
[Link]([Link] + " Enabled")
End Sub
End Class
Public Class SemaphoreDemo
Sub Main()
Dim i As Integer
For i = 1 To 15
Dim d As New Demo()
Dim t As New Thread(New ThreadStart(AddressOf [Link]))
[Link] = "T" + i
[Link]()
Next
End Sub
End Class
Code: 14.8 VB
Semaphore Example
class Demo1
{
//static Semaphore s = new Semaphore(3,3);
Semaphore s = new Semaphore(3, 3, "Test");
public void Run()
{
[Link]([Link] + " Started");
[Link]();
[Link](1000);
[Link]();
[Link]([Link] + " Ended");
}
}
class SemaphoreDemo
{
public static void Main()
{
for (int i = 0; i < 15; i++)
{
Demo1 d = new Demo1();
Thread t = new Thread( new ThreadStart([Link]));
19
Deccansoft Software Services - [Link] 4.5 Multithreading
[Link] = "T" + i;
[Link]();
}
[Link]("Main method ends");
}
}
Code: 14.8 C#
Task Parallel Programming
The Task Parallel Library (TPL) is a set of public types and APIs in the [Link] and
[Link] namespaces in the .NET Framework 4.
The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism
and concurrency to applications.
The TPL scales the degree of concurrency dynamically to most efficiently use all the processors that are
available.
In addition, the TPL handles the partitioning of the work, the scheduling of threads on the ThreadPool,
cancellation support, state management, and other low-level details.
By using TPL, you can maximize the performance of your code while focusing on the work that your program is
designed to accomplish.
Note: However, not all code is suitable for parallelization; for example, if a loop performs only a small amount of
work on each iteration, or it doesn't run for many iterations, then the overhead of parallelization can cause the
code to run more slowly.
parallelization like any multithreaded code adds complexity to your program execution.
Data parallelism refers to scenarios in which the same operation is performed concurrently (that is, in parallel) on
elements in a source collection or array. In data parallel operations, the source collection is partitioned so that
multiple threads can operate on different segments concurrently.
[Link] class provides For and Foreach methods.
class ProgramBySandeep
{
static void Main(string[] args)
{
//Demo: [Link]
Stopwatch sw = new Stopwatch();
[Link]();
FooSequencial(10, 100, 100);
[Link]();
[Link]("Sequencial For Result: " + [Link]);
[Link]();
FooParallel(10, 100, 100);
[Link]();
[Link]("Parallel For Result: " + [Link]);
//Demo: [Link]
20
Deccansoft Software Services - [Link] 4.5 Multithreading
[Link]();
FooEachSequencial();
[Link]();
[Link]("Sequential ForEach Result: " + [Link]);
[Link]();
FooEachParallel();
[Link]();
[Link]("Parallel ForEach Result: " + [Link]);
}
static void FooSequencial(int m, int n, int o)
{
for (int i = 0; i < m; i++)
{
long res = ConsumeProcessor();
//[Link](i + " " + res);
}
}
static void FooParallel(int m, int n, int o)
{
[Link](0, m, i =>
{
long res = ConsumeProcessor();
//[Link](i + " " + res);
});
}
static long ConsumeProcessor()
{
long tmp = 0;
for (int i = 0; i < 1000; i++)
for (int j = 0; j < 10000; j++)
tmp += i + j;
return tmp;
}
static void FooEachSequencial()
{
DirectoryInfo dir = new DirectoryInfo("d:\\");
FileInfo[] arFiles = [Link]("*.*");
foreach (FileInfo fi in arFiles)
{
if ()
CopyFile(fi);
}
}
static void FooEachParallel()
{
DirectoryInfo dir = new DirectoryInfo("d:\\");
FileInfo[] arFiles = [Link]("*.*");
[Link](arFiles, fi =>
{
if ()
CopyFile(fi);
});
}
static void CopyFile(FileInfo fi)
{
try
{
21
Deccansoft Software Services - [Link] 4.5 Multithreading
FileStream fs = [Link]();
byte[] buffer = new byte[[Link]];
[Link](buffer, 0, [Link]);
[Link]();
fs = new FileStream("d:\\temp\\" + [Link], [Link]);
[Link](buffer, 0, [Link]);
[Link]();
}
catch (UnauthorizedAccessException ex)
{}
}
}
22