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 urlhttp_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 urlhttp_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]


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *