Back to Course

Intermediate Python

0% Complete
0/0 Steps
Lesson 22 of 33
In Progress

Introduction to Threading

Threading is a way to run multiple threads concurrently within a single process. This can be useful for executing tasks in parallel and improving the performance of your Python program.

In this article, we will cover the basics of threading in Python and show you how to create and start threads. We will also discuss some common pitfalls to avoid when working with threads.

Creating a Thread

To create a thread in Python, we first need to import the threading module. Then, we can define a new class that inherits from the Thread class and overrides the run method. The run method is the entry point for the thread and will contain the code that the thread will execute.

Here’s an example of a simple thread that prints a message:

import threading

class PrintThread(threading.Thread):
    def __init__(self, message):
        super().__init__()
        self.message = message

    def run(self):
        print(self.message)

Starting a Thread

To start a thread, we first need to create an instance of our PrintThread class and then call the start method. The start method will create a new native thread and run the run method in the new thread.

Here’s an example of how to start a PrintThread:

thread = PrintThread("Hello from the thread!")
thread.start()

It’s important to note that the start method only initiates the execution of the thread. It does not wait for the thread to finish before moving on to the next line of code.

Joining a Thread

If you want your main thread to wait for a worker thread to finish before moving on, you can use the join method. The join method blocks the calling thread until the thread it is called on finishes execution.

Here’s an example of how to use the join method:

thread = PrintThread("Hello from the thread!")
thread.start()
thread.join()
print("Thread finished!")

In this example, the main thread will wait for the PrintThread to finish before printing the message “Thread finished!”.

Common Pitfalls

There are a few things to be aware of when working with threads in Python:

  • Python’s global interpreter lock (GIL) prevents multiple native threads from executing Python bytecodes at once. This means that only one thread can execute Python code at a time, even if you have multiple CPU cores.
  • The join method only works for threads that are started using the start method. If you create a thread using the run method instead of the start method, the join method will have no effect.
  • It’s generally a good idea to avoid shared state between threads. This can lead to race conditions and other synchronization issues. If you need to share data between threads, consider using a Queue or other thread-safe data structure.

Conclusion

In this article, we covered the basics of threading in Python. We learned how to create and start threads, and how to use the join method to wait for a thread to finish. We also discussed some common pitfalls to avoid when working with threads.

With this knowledge, you should be able to start using threads in your Python programs to improve their performance and execute tasks in parallel.

Exercises

To review these concepts, we will go through a series of exercises designed to test your understanding and apply what you have learned.

Write a program that creates a thread that prints the numbers from 1 to 10.

import threading

class PrintThread(threading.Thread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(1, 11):
            print(i)

thread = PrintThread()
thread.start()
thread.join()

Write a program that creates a thread that calculates the sum of the numbers from 1 to 100. Print the result after the thread finishes.

import threading

class SumThread(threading.Thread):
    def __init__(self):
        super().__init__()
        self.sum = 0

    def run(self):
        for i in range(1, 101):
            self.sum += i

thread = SumThread()
thread.start()
thread.join()
print(thread.sum)  # Output: 5050

Write a program that creates a thread that calculates the factorial of a given number. The number should be passed as a command line argument. Print the result after the thread finishes.

import threading
import sys

class FactorialThread(threading.Thread):
    def __init__(self, number):
        super().__init__()
        self.number = number
        self.result = 1

    def run(self):
        for i in range(2, self.number + 1):
            self.result *= i

number = int(sys.argv[1])
thread = FactorialThread(number)
thread.start()
thread.join()
print(thread.result)

Write a program that creates a thread that counts down from 10 to 1. Print each number on a separate line. Use the sleep method from the time module to pause the thread for 1 second between each number.

import threading
import time

class CountdownThread(threading.Thread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(10, 0, -1):
            print(i)
            time.sleep(1)

thread = CountdownThread()
thread.start()
thread.join()

Write a program that creates two threads: one that prints the numbers from 1 to 10, and another that prints the letters from ‘a’ to ‘j’. Use the join method to make sure that both threads finish before the program exits.

import threading

class PrintNumbersThread(threading.Thread):
    def __init__(self):
        super().__init__()

    def run(self):
        for i in range(1, 11):
            print(i)

class PrintLettersThread(threading.Thread):
    def __init__(self):
        super().__init__()

    def run(self):
        for letter in 'abcdefghij':
            print(letter)

numbers_thread = PrintNumbersThread()
letters_thread = PrintLettersThread()

numbers_thread.start()
letters_thread.start()

numbers_thread.join()
letters_thread.join()

This program will create two threads, one that prints the numbers from 1 to 10 and another that prints the letters from ‘a’ to ‘j’. The join method is called on both threads to make sure that they both finish before the program exits. The output of this program will be the numbers from 1 to 10 and the letters from ‘a’ to ‘j’ printed in an interleaved fashion.