Я читаю различные руководства по модулю многопроцессорности в Python, и мне трудно понять, почему/когда вызывать process.join()
. Например, я наткнулся на этот пример:
nums = range(100000)
nprocs = 4
def worker(nums, out_q):
""" The worker function, invoked in a process. 'nums' is a
list of numbers to factor. The results are placed in
a dictionary that pushed to a queue.
"""
outdict = {}
for n in nums:
outdict[n] = factorize_naive(n)
out_q.put(outdict)
# Each process will get 'chunksize' nums and a queue to put his out
# dict into
out_q = Queue()
chunksize = int(math.ceil(len(nums) / float(nprocs)))
procs = []
for i in range(nprocs):
p = multiprocessing.Process(
target=worker,
args=(nums[chunksize * i:chunksize * (i + 1)],
out_q))
procs.append(p)
p.start()
# Collect all results into a single result dict. We know how many dicts
# with results to expect.
resultdict = {}
for i in range(nprocs):
resultdict.update(out_q.get())
# Wait for all worker processes to finish
for p in procs:
p.join()
print resultdict
Из того, что я понимаю, process.join()
блокирует вызывающий процесс до тех пор, пока процесс, метод которого был вызван, завершил выполнение. Я также считаю, что дочерние процессы, которые были запущены в приведенном выше примере кода, завершают выполнение после завершения целевой функции, то есть после того, как они подтолкнули их результаты к out_q
. Наконец, я считаю, что out_q.get()
блокирует вызывающий процесс, пока не будут получены результаты. Таким образом, если вы считаете код:
resultdict = {}
for i in range(nprocs):
resultdict.update(out_q.get())
# Wait for all worker processes to finish
for p in procs:
p.join()
основной процесс блокируется вызовами out_q.get()
до тех пор, пока каждый отдельный рабочий процесс не завершит вывод своих результатов в очередь. Таким образом, к тому моменту, когда основной процесс выходит из цикла for, каждый дочерний процесс должен завершить выполнение, правильно?
Если это так, есть ли причина для вызова методов p.join()
в этот момент? Разве не все рабочие процессы уже завершены, и как это заставляет основной процесс "ждать завершения всех рабочих процессов"? Я прошу в основном, потому что я видел это в нескольких разных примерах, и мне любопытно, если я что-то не понял.