Threads
Threads allow programs to have more than one thing happening at once. The threads.py module provides all of the functionalities related to threads.
The Thread class is designed to execute a function in a separate thread and handle parallel processing. It extends Python's native threading capabilities with additional features such as the use of context variables and the ability to return a result from the thread. The implementation is based on a custom ThreadPool which allows the execution of functions in a controlled and concurrent manner.
Let's take a look at the methods of the Threads class:
Joining¶
The join() method waits for the thread to complete and returns the result from the thread's execution. Below we have a working example with a theoretical function that multiplies two numbers, which then returns the result of the target function after the thread is completed.
def multiply(a: int, b: int) -> int:
return a * b
thread = Thread(target=multiply, args=(3, 5))
thread.start()
thread.join()
15
Start¶
The start() method, as the name suggests, starts the thread by invoking the run() method internally. Below we have an implementation example in practice:
def concatenate(a, b):
return a + b
thread = Thread(target=concatenate, args=("Hello, ", "World!"))
thread.start()
thread.join()
'Hello, World!'
ThreadPool¶
The ThreadPool class extends ThreadPoolExecutor to provide a convenient interface for executing tasks in parallel threads while managing concurrency. It adds features such as error handling, context propagation, and result collection from threads.
from time import sleep
from everysk.core.threads import ThreadPool
def add_integers(a, b):
sleep(1)
return a + b
pool = ThreadPool(concurrency=4)
for i in range(6):
pool.add(target=add_integers, args=(i, i))
pool.wait()
print(pool.results)
[0, 2, 4, 6, 8, 10]
Add¶
The purpose of the add() method is to add a task to the thread pool to be processed later. As seen in the example above, the add() method is used to add a task to the thread pool. The add() method takes the following parameters:
-
target: The function to be executed -
args: The arguments to be passed to the function -
kwargs: Any keyword arguments to be passed to the function
In our previous ThreadPool example the add() method was implemented inside of a for loop in a way that each iteration our add_integers() function gets added with different arguments to be processed later.
Wait¶
This method is used in order to wait for all threads in the pool to complete. It is important to call this method after adding all tasks to the pool in order to ensure that all threads have completed their tasks.
Still referring to our past example, the wait() method is implemented in the following manner: