Back to Course

Intermediate Python

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

Starting and Stopping Threads

In Python, threads can be started, stopped, and joined using various methods and attributes provided by the threading module.

Starting a Thread

To start a thread, you can call the start method on the thread object. This will cause the thread’s run method to be executed in a separate thread of execution. For example:

import threading

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

    def run(self):
        print('Thread started')

thread = PrintThread()
thread.start()  # Output: 'Thread started'

Stopping a Thread

To stop a thread, you can use the stop method provided by the thread module. However, this method is not recommended because it can leave resources in an undefined state and is not guaranteed to stop the thread. Instead, it is better to use a flag variable to signal to the thread that it should stop. For example:

import threading
import time

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

    def run(self):
        while not self.stop_requested:
            print('Countdown:', self.count)
            self.count -= 1
            time.sleep(1)

thread = CountdownThread()
thread.start()
time.sleep(5)
thread.stop_requested = True
thread.join()

In this example, the CountdownThread class has a stop_requested attribute that is used to signal to the thread that it should stop. The run method checks this attribute at the beginning of each iteration and exits if it is True.

To wait for a thread to finish, you can use the join method. This method blocks the calling thread until the thread whose join method is called finishes. For example:

import threading

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

    def run(self):
        print('Thread started')

thread = PrintThread()
thread.start()
thread.join()  # Blocks until the thread finishes

The join method can also be called with a timeout argument, which specifies the maximum number of seconds to wait for the thread to finish. If the thread does not finish within the timeout period, the join method returns.

Conclusion

In summary, the start method is used to start a thread, a flag variable or some other signaling mechanism is used to stop a thread, and the join method is used to wait for a thread to finish. By using these methods and attributes, you can effectively control and manage threads in your Python programs.

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 counts down from 10 to 1. The countdown should be displayed every second. The program should allow the user to input a number n, and the countdown should be stopped when the countdown reaches n.

import threading
import time

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

    def run(self):
        for i in range(10, 0, -1):
            print('Countdown:', i)
            if i == self.stop_at:
                break
            time.sleep(1)

stop_at = int(input('Enter a number to stop the countdown at: '))
thread = CountdownThread(stop_at)
thread.start()
thread.join()

Write a program that creates a thread that prints the numbers from 1 to 10. The program should allow the user to input a string, and the thread should be stopped when the string is entered.

import threading

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

    def run(self):
        for i in range(1, 11):
            print(i)
            user_input = input()
            if user_input == self.stop_string:
                break

stop_string = input('Enter a string to stop the thread: ')
thread = PrintThread(stop_string)
thread.start()
thread.join()

Write a program that creates a thread that counts down from 10 to 1. The countdown should be displayed every second. The program should allow the user to input a number n, and the countdown should be stopped when the countdown reaches n. The program should also display the elapsed time.

import threading
import time

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

    def run(self):
        start_time = time.time()
        for i in range(10, 0, -1):
            print('Countdown:', i)
            if i == self.stop_at:
                break
            time.sleep(1)
        end_time = time.time()
        elapsed_time = end_time - start_time
        print('Elapsed time:', elapsed_time)

stop_at = int(input('Enter a number to stop the countdown at: '))
thread = CountdownThread(stop_at)
thread.start()
thread.join()

Write a program that creates a thread that counts down from 10 to 1. The countdown should be displayed every second. The program should allow the user to input a number n, and the countdown should be stopped when the countdown reaches n. The program should also allow the user to input a string, and the thread should be stopped when the string is entered. The program should display the elapsed time.

import threading
import time

class CountdownThread(threading.Thread):
    def __init__(self, stop_at, stop_string):
        super().__init__()
        self.stop_at = stop_at
        self.stop_string = stop_string

    def run(self):
        start_time = time.time()
        for i in range(10, 0, -1):
            print('Countdown:', i)
            user_input = input()
            if i == self.stop_at or user_input == self.stop_string:
                break
            time.sleep(1)
        end_time = time.time()
        elapsed_time = end_time - start_time
        print('Elapsed time:', elapsed_time)

stop_at = int(input('Enter a number to stop the countdown at: '))
stop_string = input('Enter a string to stop the countdown: ')
thread = CountdownThread(stop_at, stop_string)
thread.start()
thread.join()

Write a program that creates a thread that counts down from 10 to 1. The countdown should be displayed every second. The program should allow the user to input a number n, and the countdown should be stopped when the countdown reaches n. The program should also allow the user to input a string, and the thread should be stopped when the string is entered. The program should display the elapsed time. The program should also create a second thread that prints out the current time every 5 seconds.

import threading
import time

class CountdownThread(threading.Thread):
    def __init__(self, stop_at, stop_string):
        super().__init__()
        self.stop_at = stop_at
        self.stop_string = stop_string

    def run(self):
        start_time = time.time()
        for i in range(10, 0, -1):
            print('Countdown:', i)
            user_input = input()
            if i == self.stop_at or user_input == self.stop_string:
                break
            time.sleep(1)
        end_time = time.time()
        elapsed_time = end_time - start_time
        print('Elapsed time:', elapsed_time)

class TimeThread(threading.Thread):
    def run(self):
        while True:
            current_time = time.strftime('%H:%M:%S')
            print('Current time:', current_time)
            time.sleep(5)

stop_at = int(input('Enter a number to stop the countdown at: '))
stop_string = input('Enter a string to stop the countdown: ')
countdown_thread = CountdownThread(stop_at, stop_string)
time_thread = TimeThread()
countdown_thread.start()
time_thread.start()
countdown_thread.join()
time_thread.join()