Python threads are useful for isolating programs and performing background tasks.
import threading
import subprocess
import time
def calculate_sum(sleep, which_thread):
time.sleep(sleep)
result = 2 + 2
print(f"{which_thread}: 2 + 2 = {result}")
def sleep(time, which_thread):
process = subprocess.Popen(
["sleep", str(time)], stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
exit_code = process.wait()
status = "finished" if exit_code == 0 else "failed"
print(f"{which_thread}: sleep '{time}' {status}. exit code: {exit_code}")
if __name__ == "__main__":
threads = [
threading.Thread(target=calculate_sum, args=(0, "Thread 1",)),
threading.Thread(target=calculate_sum, args=(1, "Thread 2",)),
threading.Thread(target=sleep, args=(5, "Thread 3",)),
threading.Thread(target=sleep, args=("fail", "Thread 4",)),
]
# Start threads
for thread in threads:
thread.start()
# Wait for both threads to finish
for thread in threads:
thread.join()
# The program will continue once both threads have finished
print("Program completed.")
# Thread 1: 2 + 2 = 4
# Thread 4: sleep 'fail' failed. exit code: 1
# Thread 2: 2 + 2 = 4
# Thread 3: sleep '5' finished. exit code: 0
# Program completed.
Yet, threading in Python doesn't always inherently enhance performance. CPU-intensive executions may not fully exploit threading due to the GIL constraint but I/O-bound operations can still get some degree of benefit. There's some work on CPython that GIL may be removed in the future versions of Python (currently 3.12+ is the latest one).