How to Return Values from a Thread

Summary: in this tutorial, you will learn how to return values from a child thread to the main thread by extending the threading.Thread class.

When a Python program starts, it has a single thread called the main thread. Sometimes, you want to offload I/O tasks to new threads and execute them concurrently. Additionally, you may also want to get the return values from these threads from the main thread.

To return a value from a thread, you can extend the Thread class and store that value in the instance of the class.

The following example illustrates how to check a specified URL and return its HTTP status code in a separate thread:

from threading import Thread
import urllib.request


class HttpRequestThread(Thread):
    def __init__(self, url: str) -> None:
        super().__init__()
        self.url = url
        self.http_status_code = None
        self.reason = None

    def run(self) -> None:
        try:
            response = urllib.request.urlopen(self.url)
            self.http_status_code = response.code
        except urllib.error.HTTPError as e:
            self.http_status_code = e.code
        except urllib.error.URLError as e:
            self.reason = e.reason


def main() -> None:
    urls = [
        'https://httpstat.us/200',
        'https://httpstat.us/400'
    ]

    # create new threads
    threads = [HttpRequestThread(url) for url in urls]

    # start the threads
    [t.start() for t in threads]

    # wait for the threads to complete
    [t.join() for t in threads]

    # display the URLs with HTTP status codes
    [print(f'{t.url}: {t.http_status_code}') for t in threads]


if __name__ == '__main__':
    main()


def main() -> None:
    urls = [
        'https://httpstat.us/200',
        'https://httpstat.us/400'
    ]

    # create new threads
    threads = [HttpRequestThread(url) for url in urls]

    # start the threads
    [t.start() for t in threads]

    # wait for the threads to complete
    [t.join() for t in threads]

    # display the URLs with HTTP status codes
    [print(f'{t.url}: {t.http_status_code}') for t in threads]

Code language: Python (python)

Output:

ttps://httpstat.us/200: 200
https://httpstat.us/400: 400Code language: Python (python)

How it works.

First, define the HttpRequestThread class that extends the Thread class:

class HttpRequestThread(Thread):
# ...Code language: Python (python)

Second, define the __init__() method that accepts a URL. Inside the __init__() method adds url, http_status_code, and reason instance variables. The http_status_code will store the status code of the url at the time of checking and the reason will store the error message in case an error occurs:

def __init__(self, url: str) -> None:
    super().__init__()
    self.url = url
    self.http_status_code = None
    self.reason = NoneCode language: Python (python)

Third, override the run() method that uses the urllib library to get the HTTP status code of the specified URL and assigns it to http_status_code field. If an error occurs, it assigns the error message to the reason field:

def run(self) -> None:
    try:
        response = urllib.request.urlopen(self.url)
        self.http_status_code = response.code
    except urllib.error.HTTPError as e:
        self.http_status_code = e.code
    except urllib.error.URLError as e:
        self.reason = e.reasonCode language: Python (python)

Later, we can access the url, http_status_code, and reason from the instance of the HttpRequestThread class.

Fourth, define the main() function that creates instances of the HttpRequestThread class, start the threads, wait for them to complete, and get the result from the instances:

def main() -> None:
    urls = [
        'https://httpstat.us/200',
        'https://httpstat.us/400'
    ]

    # create new threads
    threads = [HttpRequestThread(url) for url in urls]

    # start the threads
    [t.start() for t in threads]

    # wait for the threads to complete
    [t.join() for t in threads]

    # display the URLs with HTTP status codes
    [print(f'{t.url}: {t.http_status_code}') for t in threads]Code language: Python (python)

Summary

  • Extend the Thread class and set the instance variables inside the subclass to return the values from a child thread to the main thread.
Did you find this tutorial helpful ?