gpt4 book ai didi

守护进程内的Python多处理池

转载 作者:太空宇宙 更新时间:2023-11-03 11:56:50 25 4
gpt4 key购买 nike

我针对这个问题提出了一个问题,但没有得到足够彻底的答案来解决这个问题(很可能是因为我在解释我的问题时不够严谨,而这正是我试图纠正的):Zombie process in 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)

我没有设置 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 只是随机尝试解决 Unresolved 问题。起初我以为这是僵尸 child 的问题,当我在 while 中有 self.pool.close()self.pool.join() 时发生使用 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()' 或 daemonize() 方法,print self.pool` 将抛出一个异常,表明它是 NoneType。此外,位置似乎改变了将弹出的僵尸进程的数量。

目前,我还没有添加通过 workers 运行任何东西的功能。我的问题似乎与正确设置 worker 池完全相关。如果有任何有助于解决此问题的信息或有关创建守护进程服务的建议,我将不胜感激,该守护进程服务使用工作池来使用 Popen 执行一系列命令。由于我还没有走到那一步,我不知道我面临的挑战是什么。我在想我可能只需要编写自己的池,但如果有一个很好的技巧让池在这里工作,那就太棒了。

最佳答案

解决方法是将self.pool = Pool(process=4)放在daemonize方法的最后一行。否则池最终会在某处丢失(可能在 fork 中)。然后可以在 run 方法中访问该池,该方法由您希望守护的应用程序重载。但是,不能在 stop 方法中访问池,这样做会导致 NoneType 异常。我相信有一个更优雅的解决方案,但这是有效的,这是我现在所拥有的。如果我希望 stop 在池仍在运行时失败,我将不得不向 run 添加额外的功能和某种形式的消息,但我目前不关心这个。

关于守护进程内的Python多处理池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6516508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com