If you want explicit control over the processes you're running, you want multiprocessing.Process
:
def test_3_parallel_responses():
procs = [multiprocess.Process(target=test_response) for _ in range(3)]
for proc in procs:
proc.start()
for proc in procs:
proc.join()
That's all there is to it.
There are various differences between threads and processes, but the big one is that you don't get to implicitly share values between processes; you have to pass them around (through the startup args
and return value, or through a Queue
, or some external means like a socket or pipe) or explicitly share them (through a Value
or Array
, or some external means like an file).
For a more realistic use case, you usually don't want to directly control what the processes are doing; you want to create a pool of processes, and just queue up jobs to get done by whichever process is free next. For that, you want either multiprocessing.Pool
or concurrent.futures.ProcessPoolExecutor
. The latter is a bit simpler, but requires Python 3.2 or a third-party library, so I'll show the former:
def test_3_pooled_responses():
pool = multiprocessing.Pool(3)
for i in range(3):
pool.apply(test_response)
pool.close()
pool.join()
More commonly, you want to actually pass parameters to the function. In the simplest case, this actually makes things even simpler—if you can write the sequential version as a list comprehension or map
call, you can write the parallel version as a pool.map
call. Let's say you had a test_response(host)
call that returns some value, and you wanted to run it on host1
, host2
, and host3
:
def test_3_pooled_responses():
pool = multiprocessing.Pool(3)
responses = pool.map(test_response, ['host1', 'host2', 'host3'])
pool.close()
pool.join()