Я использую python multiprocessing
, чтобы развернуть некоторые дочерние процессы для выполнения моих заданий. Существует два требования:Как отличить процессы в Multiprocessing.Pool?
- Мне нужно знать pid дочернего процесса в случае его убийства, если захочу.
- Мне нужен обратный вызов, чтобы сделать некоторые вещи после окончания работы. Поскольку эти материалы используют блокировку в родительском процессе, это невозможно сделать в дочернем процессе.
Но я получаю:
- Процесс генерироваться
by multiprocessing.Process()
имеет атрибут "PID", чтобы получить идентификатор процесса. Но я не могу добавить свой асинхронный обратный вызов, конечно, я тоже не могу ждать синхронно. - Пул процессов, созданный
multiprocessing.Pool()
, обеспечивает интерфейс обратного вызова. Но я не могу определить, какой процесс в пуле соответствует моей задаче, так как мне может понадобиться убить процесс в соответствии с конкретным заданием.
Задача дешева, здесь показана код:
import random, time
import multiprocessing
import os
class Job(object):
def __init__(self, jobid, jobname, command):
self.jobid, self.jobname, self.command = jobid, jobname, command
def __str__(self):
return "Job <{0:05d}>".format(self.jobid)
def __repr__(self):
return self.__str__()
def _run_job(job):
time.sleep(1)
print "{} done".format(job)
return job, random.choice([True, False]) # the second argument indicates whether job has finished successfully
class Test(object):
def __init__(self):
self._loc = multiprocessing.Lock()
self._process_pool = multiprocessing.Pool()
def submit_job(self, job):
with self._loc:
self._process_pool.apply_async(_run_job, (job,), callback=self.job_done)
print "submitting {} successfully".format(job)
def job_done(self, result):
with self._loc:
# stuffs after job has finished is related to some cleanning work, so it needs the lock of the parent process
job, success = result
if success:
print "{} success".format(job)
else:
print "{} failure".format(job)
j1 = Job(1, "test1", "command1")
j2 = Job(2, "test2", "command2")
t = Test()
t.submit_job(j1)
t.submit_job(j2)
time.sleep(3.1) # wait for all jobs finishing
Но теперь я не могу получить идентификатор процесса, соответствующий каждую работу. Например, мне нужно убить задание < 1>, но я не могу найти, какой процесс в пуле процессов связан с заданием < 1>, поэтому я не могу убивать работу всякий раз, когда захочу.
Если я использую multiprocessing.Process
, то я могу записать pid каждого процесса с соответствующим заданием. Но теперь я не могу добавить метод обратного вызова.
Так есть способ как получить pid дочернего процесса, так и добавить метод обратного вызова?
Интересно. У меня есть аналогичная проблема - почему бы просто не использовать список процессов? – comodoro