我对这个问题提出了一个问题,并没有得到一个足够透彻的答案来解决这个问题(很可能是由于缺乏严谨的解释我正在尝试纠正的问题):Zombie process in python multiprocessing daemon守护进程中的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)
我没有设置标准输入,输出和错误,这样我可以调试与打印报表的代码。另外,我尝试将这个池移动到几个地方,但这是唯一不会产生异常的地方。
这里有更改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
只是一个随机尝试来解决没有奏效的问题。起初,我认为这是一个僵尸儿童问题,当我在os.kill(pid, SIGTERM)
的while循环内有self.pool.close()
和self.pool.join()
时,发生了这种情况。这是在我决定开始通过print self.pool
查看泳池位置之前。这样做后,我相信守护进程启动时以及停止时,池不一样。下面是一些输出:
[email protected]:~/pyCode/jobQueue$ sudo ./jobQueue.py start
<multiprocessing.pool.Pool object at 0x1c543d0>
[email protected]:~/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
的一系列命令的守护程序服务的建议。由于我没有那么远,我不知道我面临的挑战是什么。我想我可能只需要编写自己的游泳池,但如果有一个很好的窍门可以让游泳池在这里工作,那将是惊人的。
我想我已经想出了我需要做的事情,但我不知道该怎么做。守护进程内部写入一个pid文件。无论何时调用start或stop,它都会从文件中获取守护进程的PID。我需要对池进程的PID做同样的事情,但是怎么做? –