簡體   English   中英

Python 守護進程內的多處理池

[英]Python multiprocessing pool inside daemon process

我為這個問題提出了一個問題,但沒有得到足夠徹底的答案來解決這個問題(很可能是由於在解釋我的問題時缺乏嚴謹性,這是我試圖糾正的): python multiprocessing daemon 中的僵屍進程

我正在嘗試實現一個 python 守護進程,它使用一個工作池來使用Popen執行命令。 我從http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/借用了基本的守護進程

我只更改了initdaemonize (或同樣是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查看池位置之前。 這樣做之后,我相信當守護進程啟動和停止時池是不一樣的。 這是一些 output:

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執行一系列命令的守護程序服務的建議。 由於我還沒有走那么遠,我不知道我將面臨哪些挑戰。 我在想我可能只需要編寫自己的池,但如果有一個很好的技巧可以讓池在這里工作,那就太棒了。

解決方法是將self.pool = Pool(process=4)作為daemonize方法的最后一行。 否則,池最終會在某個地方迷路(可能在fork中)。 然后可以在run方法中訪問該池,該方法被您希望守護的應用程序重載。 但是,不能在 stop 方法中訪問池,這樣做會導致 NoneType 異常。 我相信有一個更優雅的解決方案,但這很有效,這就是我現在所擁有的。 如果我希望在池仍在運行時stop失敗,我將不得不添加額外的功能來run和某種形式的消息,但我目前並不關心這個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM