无法在python3中获取子进程返回代码
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了无法在python3中获取子进程返回代码,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2418字,纯文字阅读大概需要4分钟。
内容图文
![无法在python3中获取子进程返回代码](/upload/InfoBanner/zyjiaocheng/947/e2d1dd0096de4de68053f049bd4191d3.jpg)
我试图为我的python守护进程创建类似超级用户的东西,发现相同的代码在python2中有效,而在python3中不起作用.
通常,我来介绍这个最小的示例代码.
守护进程
#!/usr/bin/env python
import signal
import sys
import os
def stop(*args, **kwargs):
print('daemon exited', os.getpid())
sys.exit(0)
signal.signal(signal.SIGTERM, stop)
print('daemon started', os.getpid())
while True:
pass
主管
import os
import signal
import subprocess
from time import sleep
parent_pid = os.getpid()
commands = [
[
'./daemon.py'
]
]
popen_list = []
for command in commands:
popen = subprocess.Popen(command, preexec_fn=os.setsid)
popen_list.append(popen)
def stop_workers(*args, **kwargs):
for popen in popen_list:
print('send_signal', popen.pid)
popen.send_signal(signal.SIGTERM)
while True:
popen_return_code = popen.poll()
if popen_return_code is not None:
break
sleep(5)
signal.signal(signal.SIGTERM, stop_workers)
for popen in popen_list:
print('wait_main', popen.wait())
如果您运行supervisor.py,然后在其pid上调用kill -15,则它将死于无限循环,因为popen_return_code永远不会不是None.我发现,这基本上是因为添加了threading.Lock用于wait_pid操作(source),但是如何重写代码以使其能够正确处理子退出?
解决方法:
这是一个有趣的案例.
我花了几个小时试图弄清楚为什么会发生这种情况,而我现在想到的唯一一件事就是,在python3和python2.7中已经更改了wait()和poll()的实现.
查看python3 / suprocess.py实现的源代码,我们可以看到调用Popen对象的wait()方法时发生了锁获取,请参见
https://github.com/python/cpython/blob/master/Lib/subprocess.py#L1402.
此锁可防止进一步的poll()调用按预期工作,直到由wait()获得的锁被释放为止,请参见
https://github.com/python/cpython/blob/master/Lib/subprocess.py#L1355
并在那里发表评论
Something else is busy calling waitpid. Don’t allow two
at once. We know nothing yet.
python2.7 / subprocess.py中没有这样的锁,因此这看起来像是它在python2.7中起作用而在python3中不起作用的原因.
但是我没有看到为什么要尝试在信号处理程序中进行poll()的原因,请尝试按以下方式重写您的supervisor.py,这应该在python3和python2.7上都能正常工作
主管
import os
import signal
import subprocess
from time import sleep
parent_pid = os.getpid()
commands = [
[
'./daemon.py'
]
]
popen_list = []
for command in commands:
popen = subprocess.Popen(command, preexec_fn=os.setsid)
popen_list.append(popen)
def stop_workers(*args, **kwargs):
for popen in popen_list:
print('send_signal', popen.pid)
popen.send_signal(signal.SIGTERM)
signal.signal(signal.SIGTERM, stop_workers)
for popen in popen_list:
print('wait_main', popen.wait())
希望这可以帮助
内容总结
以上是互联网集市为您收集整理的无法在python3中获取子进程返回代码全部内容,希望文章能够帮你解决无法在python3中获取子进程返回代码所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。