multiprocessing uses separate processes for true CPU parallelism, bypassing the GIL. Pool.map() runs a function on many items in parallel. All arguments must be picklable. ProcessPoolExecutor is the modern API.
Multiprocessing
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == "__main__":
with Pool(4) as pool:
results = pool.map(square, range(10))
print(results) # [0, 1, 4, 9, ...]
# ProcessPoolExecutor (modern)
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as ex:
results = list(ex.map(square, range(10)))