我對這個問題提出了一個問題,並沒有得到一個足夠透徹的答案來解決這個問題(很可能是由於缺乏嚴謹的解釋我正在嘗試糾正的問題):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做同樣的事情,但是怎麼做? –