Unit-II Exception Handling and Multithreading
Unit-II Exception Handling and Multithreading
Handling and
Multithreading
Contents
• Exception Handling: Handling an exception, Exception
Hierarchy, The Exception Model, Run Time Errors,
try…….except…….else, try-finally-clause, Argument of an
exception, Python standard exceptions and user defined
exceptions, Handling IO Exceptions.
• Multithreading: Starting a new thread, the threading module,
synchronizing threads, race condition, multithreaded priority
queue.
Errors in Python
• Error in Python can be of two types i.e. Syntax errors and
Exceptions. Errors are the problems in a program due to which
the program will stop the execution. On the other hand,
exceptions are raised when some internal events occur which
changes the normal flow of the program.
• The difference between Syntax Error and Exceptions
• Syntax Error: As the name suggest this error is caused by
wrong syntax in the code. It leads to the termination of the
program.
Exceptions
• Exceptions: Exceptions are raised when the program is
syntactically correct but the code resulted in an error. This
error does not stop the execution of the program, however, it
changes the normal flow of the program.
• Example:-
• # initialize the amount variable
• marks = 10000
try:
divideNos(10, 0)
except:
print('some exception occurred')
• when a python interpreter raises an exception, it is in the
form of an object that holds information about the
exception type and message.
• Also, every exception type in python inherits from the
base class Exception.
Example:-
def divideNos(a, b):
return a/b
try:
divideNos(10, 0)
# Any exception raised by the python interpreter, is inherited by
the base class ‘Exception’, hence any exception raised in the try
block will be detected and collected further in the except block
for handling.
except Exception as e:
print(e) # as e is an object of type Exception, Printing here to
see what message it holds.
print(e.__class__)
Keyword for Exception Handling
• Try
• Except
• Raise
• Else
• Finally
Catching Specific Exceptions in Python
try:
a = 123
print('isStringEmpty:', isStringEmpty(a))
except ValueError as e:
print('ValueError raised:', e)
except TypeError as e:
print('TypeError raised:', e)
try except and ELSE!
• Sometimes you might have a use case where you want to run
some specific code only when there are no exceptions.
• For such scenarios, the else keyword can be used with
the try block.
• Note that this else keyword and its block are optional.
• Syntax with Else:
• try:
• # on some specific condition or otherwise
• raise SomeError(OptionalMsg)
• except SomeError as e:
• # Executed if we get an error in the try block
• # Handle exception ‘e’ accordingly
• else
• # Executed if no exceptions are raised
When an exception is not raised, it flows into the
optional else block.
Example:-
try:
b = 10
c=2
a = b/c
print(a)
except:
print('Exception raised')
else:
print('no exceptions raised')
• In the above code, As both the inputs are greater than 0 which is
not a risk to DivideByZeroException,
• hence try block won’t raise any exception and hence ‘except’
block won’t be triggered.
• And only when the control doesn’t flow to the except block, it
flows to the else block.
• Further handling can be done inside this else block if there is
something you want to do.
Try Clause with Finally
• Finally is a keyword that is used along with try and except,
when we have a piece of code that is to be run irrespective of
if try raises an exception or not.
• Code inside finally will always run after try and except.
Example:
try:
temp = [1, 2, 3]
temp[4]
except Exception as e:
print('in exception block: ', e)
else:
print('in else block')
finally:
print('in finally block')
Demonstration-I
Output
Demonstration-II
Output
Demonstration-III
Output
Demonstration-IV
Output
Demonstration-V
Output
Customized Exception
• Python has numerous built-in exceptions that force your
program to output an error when something in the program
goes wrong.
• However, sometimes you may need to create your own
custom exceptions that serve your purpose.
• In Python, users can define custom exceptions by creating a
new class. This exception class has to be derived, either
directly or indirectly, from the built-in Exception class. Most of
the built-in exceptions are also derived from this class.
• When we are developing a large Python program, it is a
good practice to place all the user-defined exceptions
that our program raises in a separate file.
• Many standard modules do this. They define their
exceptions separately
as exceptions.py or errors.py (generally but not always).
• User-defined exception class can implement everything
a normal class can do, but we generally make them
simple and concise.
• Most implementations declare a custom base class and
derive others exception classes from this base class.
# define Python user-defined exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
class ValueTooSmallError(Error):
"""Raised when the input value is too small"""
pass
class ValueTooLargeError(Error):
"""Raised when the input value is too large"""
pass
• Today, the CPU often has multiple cores, e.g., two cores
(dual-core) and four cores (quad-core).
• A dual-core CPU can execute exactly two processes,
and a quad-core CPU can execute four processes
simultaneously.
• Generally, the more cores the CPU has, the more
processes it can truly execute simultaneously.
• Multiprocessing uses a multi-core CPU within a
single computer, which indeed executes multiple
processes in parallel.
Process
In computing, a process is an instance of a computer
program that is being executed. Any process has 3 basic
components:
•An executable program.
•The associated data needed by the program
(variables, work space, buffers, etc.)
•The execution context of the program (State of
process)
•A process is basically the program in execution. When you
start an application in your computer (like a browser or text
editor), the operating system creates a process.
•A thread is an entity within a process that can be
scheduled for execution. Also, it is the smallest unit of
processing that can be performed in an OS (Operating
System).
To understand processes and threads, consider this scenario: An
.exe file on your computer is a program. When you open it, the
OS loads it into memory, and the CPU executes it. The instance
of the program which is now running is called the process.
Every process will have 2 fundamental components:
•The Code
•The Data
Now, a process can contain one or more sub-parts
called threads. This depends on the OS architecture. You can
think about a thread as a section of the process which can be
executed separately by the operating system.
In other words, it is a stream of instructions which can be run
independently by the OS. Threads within a single process share
the data of that process and are designed to work together for
facilitating parallelism.
Thread
• In simple words, a thread is a sequence of such instructions within a
program that can be executed independently of other code. For
simplicity, you can assume that a thread is simply a subset of a
process!
• A thread contains all this information in a Thread Control Block
(TCB):
1. Thread Identifier: Unique id (TID) is assigned to every new thread
2. Stack pointer: Points to thread’s stack in the process. Stack
contains the local variables under thread’s scope.
3. Program counter: a register which stores the address of the
instruction currently being executed by thread.
4. Thread state: can be running, ready, waiting, start or done.
5. Thread’s register set: registers assigned to thread for
computations.
6. Parent process Pointer: A pointer to the Process control block
(PCB) of the process that the thread lives on.
Multiple Threads
• Multiple threads can exist within one process where:
• Each thread contains its own register set and local variables
(stored in stack).
• All thread of a process share global variables (stored in
heap) and the program code.
• Consider the diagram below to understand how multiple
threads exist in memory:
When to Use
• Multithreading is very useful for saving time and improving
performance, but it cannot be applied everywhere.
In the previous example, the music thread is independent of
the thread that takes your input and the thread that takes
your input is independent of the thread that runs your
opponent. These threads run independently because they are
not inter-dependent.
• Therefore, multithreading can be used only when the
dependency between individual threads does not exist.
Benefits of Multithreading
1. It ensures effective utilization of computer system
resources.
2. Multithreaded applications are more responsive.
3. It shares resources and its state with sub-threads (child)
which makes it more economical.
4. It makes the multiprocessor architecture more effective due
to similarity.
5. It saves time by executing multiple threads at the same
time.
6. The system does not require too much memory to store
multiple threads.
Applications
• Web Browsers - A web browser can download any number of
files and web pages (multiple tabs) at the same time and still
lets you continue browsing. If a particular web page cannot be
downloaded, that is not going to stop the web browser from
downloading other web pages.
• Web Servers - A threaded web server handles each request
with a new thread. There is a thread pool and every time a
new request comes in, it is assigned to a thread from the
thread pool.
• Computer Games - You have various objects like cars, humans,
birds which are implemented as separate threads. Also playing
the background music at the same time as playing the game is
an example of multithreading.
• Text Editors - When you are typing in an editor, spell-checking,
formatting of text and saving the text are done concurrently
by multiple threads. The same applies for Word processors
also.
• IDE - IDEs like Android Studio run multiple threads at the same
time. You can open multiple programs at the same time. It
also gives suggestions on the completion of a command which
is a separate thread.
What is Multithreading in Python?
• Multithreading in Python programming is a well-known
technique in which multiple threads in a process share their
data space with the main thread which makes information
sharing and communication within threads easy and efficient.
• Threads are lighter than processes.
• Multi threads may execute individually while sharing their
process resources.
• The purpose of multithreading is to run multiple tasks and
function cells at the same time.
How to create thread in python
• Threads in Python can be created in three ways:
1. Without creating a class
2. By extending Thread class
3. Without extending Thread class
There are two main modules of multithreading used to
handle threads in Python