Processes are independent instances of a program in execution.
Each process:
Threads are smallest unit of execution within a process.
Multiple threads within same process share memory space.
import threading
import time
def print_numbers():
for i in range(5):
print(f"Thread: {i}")
time.sleep(1)
# Create new thread object to run `print_numbers`
thread = threading.Thread(target=print_numbers)
# Start thread
thread.start()
# Wait for thread to finish before exiting main program
thread.join()
print("Main thread: execution finished")Multithreading allows multiple threads to run concurrently within same process.
NOTE: in Python, true parallelism using multithreading is limited by Global Interpreter Lock (GIL), which allows only one thread to execute Python bytecode at a time.
import threading
import time
def worker(name):
print(f"Worker {name} starting")
time.sleep(2)
print(f"Worker {name} finished")
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
Multiprocessing involves running multiple processes, each with its own Python interpreter and memory space.
import multiprocessing
import time
def worker(name):
print(f"Worker {name} starting")
time.sleep(2)
print(f"Worker {name} finished")
if __name__ == "__main__":
processes = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
processes.append(p)
p.start()
for p in processes:
p.join()
asyncioasyncio is a Python library for writing concurrent code using async/await syntax.
asyncioasync def
asyncioasyncio that manages execution of tasksasyncio Exampleimport asyncio
async def task(name):
print(f"Task {name} starting")
await asyncio.sleep(2)
print(f"Task {name} finished")
async def main():
await asyncio.gather(task("A"), task("B"), task("C"))
asyncio.run(main())
asyncioasyncio is not well-suited for CPU-bound tasks since they can block event loop; however, CPU-bound tasks can be offloaded to separate thread or process using asyncio.to_thread() or asyncio.run_in_executor(), respectively.
asyncioimport asyncio
import time
def cpu_bound_task(n):
time.sleep(n)
return n * n
async def main():
result = await asyncio.to_thread(cpu_bound_task, 2)
print(f"Result: {result}")
asyncio.run(main())