CS307 Lecture 1
CS307 Lecture 1
● In clothes, thread hold the cloth together and on the other side, in computer
programming, thread hold the computer program and allow the program to execute
sequential actions or many actions at once.
Disadvantages:
●
2. Kernel Level Threads
● Operating System managed threads act on kernel, which is an
operating system core.
● In this case, the Kernel does thread management. There is no
thread management code in the application area. Kernel threads
are supported directly by the operating system. Any application
can be programmed to be multithreaded. All of the threads
within an application are supported within a single process.
● The Kernel maintains context information for the process as a
whole and for individual threads within the process. Scheduling
by the Kernel is done on a thread basis. The Kernel performs
thread creation, scheduling and management in Kernel space.
Kernel threads are generally slower to create and manage than
the user threads.
Kernel Level Threads
The examples of kernel level threads are Windows, Solaris.
Advantages:
● Kernel can simultaneously schedule multiple threads from the same process on
multiple processes.
● If one thread in a process is blocked, the Kernel can schedule another thread of the same process.
● Kernel routines themselves can be multithreaded.
Disadvantages:
● Kernel threads are generally slower to create and manage than the user threads.
● Transfer of control from one thread to another within the same process requires a mode switch to
the Kernel.
Thread Control Block (TCB)
Thread Control Block (TCB) may be defined as the data structure in
the kernel of operating system that mainly contains information about
thread. Thread-specific information stored in TCB would highlight
some important information about each process..
Consider the following points related to the threads contained in TCB:
● Thread identification − It is the unique thread id (tid) assigned to every new thread.
● Thread state − It contains the information related to the state (Running, Runnable, Non-Running, Dead) of the thread.
● Program Counter (PC) − It points to the current program instruction of the thread.
● Register set − It contains the thread’s register values assigned to them for computations.
● Stack Pointer − It points to the thread’s stack in the process. It contains the local variables under thread’s scope.
● Pointer to PCB − It contains the pointer to the process that created that thread
Process vs Thread
● In multithreading, process and thread are two very closely related terms having the same goal to make
computer able to do more than one thing at a time. A process can contain one or more threads but on the
contrary, thread cannot contain a process. However, they both remain the two basic units of execution. A
program, executing a series of instructions, initiates process and thread both.
Process Thread
1. Process is heavy weight or resource intensive. 1. Thread is lightweight which takes fewer resources than a
2. Process switching needs interaction with operating system. process.
3. In multiple processing environments, each process executes 2. Thread switching does not need to interact with operating
the same code but has its own memory and file resources. system.
4. If one process is blocked, then no other process can execute 3. All threads can share same set of open files, child processes.
until the first process is unblocked. 4. While one thread is blocked and waiting, a second thread in
5. Multiple processes without using threads use more the same task can run.
resources. 5. Multiple threaded processes use fewer resources.
6. In multiple processes, each process operates 6. One thread can read, write or change another thread's
independently of the others. data.
7. If there would be any change in the parent process then it 7. If there would be any change in the main thread then it
does not affect the child processes. may affect the behavior of other threads of that process.
8. To communicate with sibling processes, processes must 8. Threads can directly communicate with other threads of
use inter-process communication. that process.
Multithreading
The following diagram helps us understand how multiple
threads exist in memory −
2. <threading> module : treats every thread as an object and implements it in an object oriented way
● <_thread>module is effective in low level threading and has fewer capabilities than the <threading>
module.
<threading> module
● The <threading> module implements in an object oriented way and treats every thread as an object. Therefore,
it provides much more powerful, high-level support for threads than the <_thread> module. This module is
included with Python 2.4.
● Additional methods of <threading> module: The <threading> module comprises all the methods of the
<_thread> module but it provides additional methods as well. The additional methods are as follows −
● threading.activeCount() − This method returns the number of thread objects that are active
● threading.currentThread() − This method returns the number of thread objects in the caller's thread
control.
● threading.enumerate() − This method returns a list of all thread objects that are currently active.
● For implementing threading, the <threading> module has the Thread class which
provides the following methods −
● run() − The run() method is the entry point for a thread
● start() − The start() method starts a thread by calling the run method.
● join([time]) − The join() waits for threads to terminate.
● isAlive() − The isAlive() method checks whether a thread is still executing.
● getName() − The getName() method returns the name of a thread.
● setName() − The setName() method sets the name of a thread.
How to create threads using <threading>
module?
Follow these steps to create a new thread using the <threading> module −
● Step 1 − In this step, we need to define a new subclass of the Thread class.
● Step 2 − Then for adding additional arguments, we need to override the __init__(self [,args]) method.
● Step 3 − In this step, we need to override the run(self [,args]) method to implement what the thread
should do when started.
Now, after creating the new Thread subclass, we can create an instance of it and then start a new thread by
invoking the start(), which in turn calls the run() method.
Example
Consider this example to learn how to generate
a new thread by using the <threading> module.
Output
Now, consider the following output −
Python program for various thread states
There are five thread states - new, runnable, running,
waiting and dead. Among these five Of these five, we
will majorly focus on three states - running, waiting
and dead. A thread gets its resources in the running
state, waits for the resources in the waiting state; the
final release of the resource, if executing and
acquired is in the dead state.
● Race Condition:- A race condition may be defined as the occurring of a condition when two or more
threads can access shared data and then try to change its value at the same time. Due to this, the
values of variables may be unpredictable and vary depending on the timings of context switches of
the processes.
Example-Race Condition
Consider this example to understand the concept of race condition −
Dealing with race condition using locks
● In Python, the <threading>module provides Lock class to deal with race condition. Further, the Lock class provides
different methods with the help of which we can handle race condition between multiple threads. The methods are
described below −
1. acquire() method
This method is used to acquire, i.e., blocking a lock. A lock can be blocking or non-blocking depending upon the following true
or false value −
● With value set to True − If the acquire() method is invoked with True, which is the default argument, then the
thread execution is blocked until the lock is unlocked.
● With value set to False − If the acquire() method is invoked with False, which is not the default argument, then
the thread execution is not blocked until it is set to true, i.e., until it is locked.
2. release() method
This method is used to release a lock. Following are a few important tasks related to this method −
● If a lock is locked, then the release() method would unlock it. Its job is to allow exactly one thread to proceed if more
than one threads are blocked and waiting for the lock to become unlocked.
● It will raise a ThreadError if lock is already unlocked.
Python program to understand the concept of locks for dealing
with race condition −
Deadlocks − The Dining Philosophers problem
● Deadlock is a troublesome issue one can face while designing the concurrent systems. We can
illustrate this issue with the help of the dining philosopher problem as follows:-
● In this problem, there are five famous philosophers sitting at a round table eating some food from
their bowls. There are five forks that can be used by the five philosophers to eat their food. However,
the philosophers decide to use two forks at the same time to eat their food.
● Now, there are two main conditions for the philosophers. First, each of the philosophers can be either
in eating or in thinking state and second, they must first obtain both the forks, i.e., left and right.
● The issue arises when each of the five philosophers manages to pick the left fork at the same time.
Now they all are waiting for the right fork to be free but they will never relinquish their fork until
they have eaten their food and the right fork would never be available. Hence, there would be a
deadlock state at the dinner table
Solution- The Dining Philosophers problem
● The solution of this problem can be found by splitting the philosophers into two types – greedy
philosophers and generous philosophers.
● Mainly a greedy philosopher will try to pick up the left fork and wait until it is there. He will then
wait for the right fork to be there, pick it up, eat and then put it down.
● On the other hand, a generous philosopher will try to pick up the left fork and if it is not there, he will
wait and try again after some time. If they get the left fork then they will try to get the right one. If
they will get the right fork too then they will eat and release both the forks.
Solution with Python program
The Below program uses the concept of greedy and generous philosophers. The program has also used the acquire()
and release() methods of the Lock class of the <threading> module
References
● https://www.tutorialspoint.com/concurrency_in_python/concurrency_in_python_threads.htm