Я открыл вопрос для этой проблемы и не получил достаточно подробного ответа для решения проблемы (скорее всего из-за недостатка строгости в объяснении моих проблем, что я и пытаюсь исправить): Зомбипроцесс в демоне многопроцессорной обработки 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, чтобы я мог отлаживать код с помощью операторов print.Кроме того, я попытался переместить этот пул в несколько мест, но это единственное место, где нет исключений.
Вот изменения в методе 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
daemonize () methods,
print, то self.pool` выдаст исключение, сообщающее, что это NoneType.Кроме того, местоположение, кажется, изменяет количество процессов, которые будут появляться в зомби.
В настоящее время я не добавил функциональность для запуска чего-либо через рабочих.Кажется, моя проблема полностью связана с правильной настройкой пула работников.Буду признателен за любую информацию, которая приведет к решению этой проблемы, или за советы по созданию службы демона, которая использует пул рабочих для выполнения серии команд с использованием Popen
.Так как я не зашел так далеко, я не знаю, с какими проблемами я столкнусь впереди.Я думаю, что мне, возможно, просто нужно написать свой собственный пул, но если есть хороший трюк, чтобы заставить пул работать здесь, это было бы удивительно.