Multithreading can be fun too! [Part 1]

Introduction

Punyatoya Soumya Darshinee
6 min readApr 5, 2020

Greetings!!! I am sure you might have splashed down here in search of some details or answers to your queries related to Multi-threading. I hope this post will somehow fuel your desire to learn and apply multithreaded concepts to solve real-world problems.

Get Set Go!!!…

Given the many benefits, Multi-threading provides, I have seen people getting scared and refraining from switching to multithreaded programs from their single-threaded programs. I also used to think that multithreading is too complicated, too complex, and I would end up in the tangled threads. Ha Ha!!!

I was working on a project recently, where I had to boost the efficiency of the Backup operation. There were two approaches to whether to go for single-threaded that was easy but no idea how much it would offer throughout (so a lot of unknowns). And the other way was to use multi-threading, too complex for me as I had the perception (multi-threading was not my cup of tea).

The multi-threaded architecture calculations that I had in mind were providing me full assurance that this will increase the performance. Why not!!! So instead of going for the single-threaded approach whose results are unknown, I decided to took up the challenge of writing the code using a multi-threading concept. I started learning from the very basics and eventually completed code changes in a few days. And the results were mind-boggling. It was giving a drastic increase in performance.

I realized that it looks hard to multi-thread, but it’s not. Since all possible scenarios and problems of multi-threading are well-known. We just have to follow basic, well-known development practices.

The main aim of this blog is to make you understand the concept of threads and help you come out of the fear of “Multithreading”. Let’s start the basics from the beginning as the famous quote says “Well begun is half done

First, Let’s just talk about what is Thread?

The smallest unit of computation that can be scheduled by an operating system or a scheduler.

It is a light-weight process that operates independently.

And What does lightweight and being operated independently means?

Well, it uses fewer resources as compared to the Process (resources allocated to the process) that’s why it is lightweight. And CPU executes thread independently of other codes.

What’s its relationship with the process?

A process is a program in execution and can have many threads. So threads are units of execution within a process. I would say sort of small tasks within a big running task.

Is it possible to create a thread without a process?

No, not at all. How do we envisage a thread without any logical program? That would deny the whole existence of a thread.

Does every thread have a process?

Of course, the thread is a subset of the process.

Can you create a thread inside a thread?

No. We can have two-generation threads for e.g Consider the process has a main thread which is the 0th generation (which is always one) and many child threads which are 1st generation can be called sibling threads. After 1st gen we can’t have threads, then it’s very difficult to manage them. The whole concept of multithreading would come to an end.

Advantages

Improves Throughput(performance enhancement)

Multithreading improves performance by allowing multiple CPUs to work on a problem at the same time.

We can also use threads to improve appeared performance (or responsiveness) in an interactive application. We run heavy computations on a background thread to avoid blocking UI interactions. Our computations do not complete faster, but Our application does not have those “hangs” that make it appear slow and unresponsive.

Better CPU Utilization and Scalability

For CPU bound tasks where you have more than one core in your processor, you can divide your work on each of your processor cores. If you have two cores, split the work into two threads. This way you have two threads working at full speed.

The benefits of multi-threading greatly increase in the case of multiprocessor architecture, where threads may be running parallel on multiple processors.

Simplified and streamlined program coding

Threads can be used to simplify the structure of complex applications, such as server-class and multimedia applications. Simple routines can be written for each activity, making complex programs easier to design and code, and more adaptive to a wide variation in user demands.

The simultaneous and parallelized occurrence of tasks

Many concurrent compute operations and I/O requests within a single process. Simultaneous and fully symmetric use of multiple processors for computation and I/O

Resource sharing

Sharing large amounts of data through separate threads of execution within the same address space provides extremely high-bandwidth, low-latency communication between separate tasks within an application.

Drop the Delusion

“Multi-threading is Hard”, But It’s not. If a multithreaded program is unreliable or inefficient, it’s most likely due to the same reasons that single-threaded programs fail. The reason is very simple: The programmer didn’t follow basic, well-known development practices. Most of what they were taught in introductory multithreading materials is technically correct but completely irrelevant to the problems at hand.

The most important concepts in programming are universal; they apply equally to single-threaded and multithreaded programs. So Multithreading is not hard, It’s just the misconception we have in our mind. Many software programmers are likely to experience Multi-threading scenarios that are well known and implemented in libraries that hide the bewildering complexity of dealing with concurrency. We should use those libraries in the same way that we use libraries of user interface controls, communications protocols, and the countless other tools that simplify our jobs.

How to create threads in Python

The ”threading” module in Python offers a very basic and intuitive API for spawning multiple threads within a program.

Let’s start writing the code:

To import the “threading” module, we have to do this:

import threading

In order to create new threads, we create objects of Thread Class. It takes the following arguments:

  • target: the function to be executed by a thread
  • args: the arguments to be passed to the target function

In below example, we have created two threads with different target functions addition and subtraction:

first_thread = threading.Thread(target=addition, args=(10,3))
second_thread = threading.Thread(target=subtraction, args=(10,3))

To start a thread, we use the start() method of the Thread class. It starts the thread’s activity.

first_thread.start()
second_thread.start()

Once the threads start, the current program (or we can say the main thread) also keeps on executing. In order to stop the execution of the current program until a thread is complete, we use the “.join” method.

join() Wait until the thread terminates.

first_thread.join()
second_thread.join()

As a result, the current program will wait for first_thread to be done first, and then second_thread. When they are over, the remainder of the existing program statements is executed.

Python3 Code Snippet

Multi-threaded code

Output

C:\Users\darshp\PycharmProjects\untitled1\venv\Scripts\python.exe C:/Users/darshp/PycharmProjects/untitled1/test_thread.py
Addition: 13
Subtraction: 7
Toodles!

Process finished with exit code 0

Conclusion

Well, learning takes time, but we can master them all if we start with small and quality steps.

I’m coming up with the next Multi-threading post soon. I think the fear of coding or debugging the Multithreaded programs will gradually and steadily diminish among our fellow programmers.

Let’s end this with the quote:

“Learn Little, But Learn Often”

TOODLES for now!!! To be continued…

If you find this article a bit interesting, please follow me on the Medium and give me a few claps. You can also follow me on Linkedln. Thanks for reading!!!

--

--