методы для очистки бассейна красиво. Любые другие решения будут оценены.
рыл вопрос для этой проблемы и не получил достаточно подробного ответа, чтобы решить проблему (скорее всего из-за недостатка строгости в объяснении моих проблем, что я и пытаюсь исправить):Зомби-процесс в многопроцессорном демоне python
Я пытаюсь реализовать демон Python, который использует пул рабочих для выполнения команд с помощьюPopen
, Я позаимствовал основной демон отhttp://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
Я только изменилinit
, daemonize
(или в равной степениstart
) а такжеstop
методы. Вот изменения вinit
метод:
def __init__(self, pidfile):
#, stdin='/dev/null', stdout='STDOUT', stderr='STDOUT'):
#self.stdin = stdin
#self.stdout = stdout
#self.stderr = stderr
self.pidfile = pidfile
self.pool = Pool(processes=4)
Я не устанавливаю stdin, stdout и stderr, чтобы я мог отлаживать код с помощью операторов печати. Кроме того, я попытался переместить этот пул в несколько мест, но это единственное место, где нет исключений.
Вот изменения вdaemonize
метод:
def daemonize(self):
...
# redirect standard file descriptors
#sys.stdout.flush()
#sys.stderr.flush()
#si = open(self.stdin, 'r')
#so = open(self.stdout, 'a+')
#se = open(self.stderr, 'a+', 0)
#os.dup2(si.fileno(), sys.stdin.fileno())
#os.dup2(so.fileno(), sys.stdout.fileno())
#os.dup2(se.fileno(), sys.stderr.fileno())
print self.pool
...
То же самое, я не перенаправляю IO, чтобы я мог отлаживать. Печать здесь используется, чтобы я мог проверить расположение бассейнов.
Иstop
изменения метода:
def stop(self):
...
# Try killing the daemon process
try:
print self.pool
print "closing pool"
self.pool.close()
print "joining pool"
self.pool.join()
print "set pool to None"
self.pool = None
while 1:
print "kill process"
os.kill(pid, SIGTERM)
...
Идея в том, что мне нужно не только убить процесс, но и очистить пул.self.pool = None
это просто случайная попытка решить проблемы, которые не сработали. Сначала я подумал, что это проблема с детьми-зомби, которая возникала, когда у меняself.pool.close()
а такжеself.pool.join()
внутри цикла while сos.kill(pid, SIGTERM)
, Это прежде, чем я решил начать смотреть на расположение бассейна черезprint self.pool
, После этого я считаю, что пулы не совпадают при запуске и при остановке демона. Вот некоторые результаты:
me@pc:~/pyCode/jobQueue$ sudo ./jobQueue.py start
<multiprocessing.pool.Pool object at 0x1c543d0>
me@pc:~/pyCode/jobQueue$ sudo ./jobQueue.py stop
<multiprocessing.pool.Pool object at 0x1fb7450>
closing pool
joining pool
set pool to None
kill process
kill process
... [ stuck in infinite loop]
Различное расположение объектов подсказывает мне, что они не являются одним и тем же пулом и что один из них, вероятно, зомби?
ПослеCTRL+C
вот что я получаюps aux|grep jobQueue
:
root 21161 0.0 0.0 50384 5220 ? Ss 22:59 0:00 /usr/bin/python ./jobQueue.py start
root 21162 0.0 0.0 0 0 ? Z 22:59 0:00 [jobQueue.py] <defunct>
me 21320 0.0 0.0 7624 940 pts/0 S+ 23:00 0:00 grep --color=auto jobQueue
Я пытался переместитьself.pool = Pool(processes=4)
в ряде разных мест. Если он перемещен вstart()' or
демон ()methods,
print self.pool` выдаст исключение, сообщающее, что это NoneType. Кроме того, локация, похоже, меняет номер зомби-процесса, который появится.
В настоящее время я не добавил функциональности для запуска чего-либо через рабочих. Кажется, моя проблема полностью связана с правильной настройкой пула работников. Буду признателен за любую информацию, которая приведет к решению этой проблемы, или совет по созданию службы демона, которая использует пул рабочих для выполнения ряда команд с использованиемPopen
, Так как я не зашел так далеко, я не знаю, с какими проблемами я столкнусь впереди. Я думаю, что мне, возможно, просто нужно написать свой собственный пул, но если есть хороший трюк, чтобы заставить пул работать здесь, это было бы удивительно.