[英]psutil always returning pid exists
I have Flask application that exposed API that can run application in background and can kill it later by specifying the PID. 我有Flask应用程序,该应用程序公开了可以在后台运行应用程序的API,以后可以通过指定PID杀死它。 However, for unit testing purpose, after killing the PID and checking if the PID is killed using
psutil.pid_exists(pid)
it seems to always returning true. 但是,出于单元测试的目的,在杀死PID并使用
psutil.pid_exists(pid)
检查PID是否被杀死psutil.pid_exists(pid)
它似乎总是返回true。 I have checked manually that PID does not exist and run psutil.pid_exists(pid)
on different python console and it returned true. 我已经手动检查了PID是否不存在,并在其他python控制台上运行
psutil.pid_exists(pid)
并返回true。 This is causing my test to fail. 这导致我的测试失败。
In views.py
, I have: 在
views.py
,我有:
@api.route('/cancel/<pid>', methods=['POST'])
def cancel(pid=None):
try:
os.kill(int(pid), signal.SIGTERM)
data = dict(
message = 'Successfully killed pid ' + pid)
return jsonify(status='success', data=data), 200
except:
data = dict(
message = 'Fail to kill job with pid ' + pid)
return jsonify(status='error', data=data), 400
And in my test: 在我的测试中:
def test_cancel_job(self):
# run_script will run something in the background and return the PID
jobid, pid, cmd = run_script('fake_db', 'fake_cancel_jobid', 'tests/doubles/child.py')
if not psutil.pid_exists(pid):
raise Exception('Process is not running')
# kill the job and assert it is successful
resp = self.client.post('/api/cancel/' + str(pid))
self.assert200(resp)
# at this point, I have confirmed that the PID has been killed
# but, the line below still get executed
# psutil.pid_exists(pid) returns true
# check pid is really killed
if psutil.pid_exists(pid):
raise Exception('Process {0} still exist'.format(pid))
I'm running on OSX if that make any difference. 如果有任何区别,我正在OSX上运行。
Update: I've tried running on the test on my build server (Ubuntu 14.04) and the test failed. 更新:我尝试在构建服务器(Ubuntu 14.04)上的测试上运行,但测试失败。
This is my run_script
这是我的
run_script
def run_script(db, jobid, script):
log = SCRIPTS_LOG + jobid + ".log"
if not os.path.exists(SCRIPTS_LOG):
os.makedirs(SCRIPTS_LOG)
with open(log, "w") as output:
cmd = ["nohup", "python", script, db]
p = subprocess.Popen(cmd, stdout=output)
return jobid, p.pid, " ".join(cmd)
and my child.py
和我的
child.py
#!/usr/bin/env python
import time
import os, sys
if 'TEST_ENV' not in os.environ:
os.environ['TEST_ENV'] = 'Set some env'
try:
os.execv(sys.argv[0], sys.argv)
except Exception, exc:
print "Failed re-exec:", exc
sys.exit(1)
def main(argv):
db = argv[0]
while True:
print 'Running child with params ', db
time.sleep(1)
if __name__ == '__main__':
main(sys.argv[1:])
I added a simple scripts that demonstrate this. 我添加了一个简单的脚本来演示这一点。 https://github.com/shulhi/kill-pid/tree/master
https://github.com/shulhi/kill-pid/tree/master
It takes time to terminate a running process. 终止正在运行的进程需要花费时间。 In this case it's a child process, so
os.wait()
or one of its variants will know exactly how long to wait. 在这种情况下,它是一个子进程,因此
os.wait()
或其变体之一将确切知道要等待多长时间。 To future-proof, i'd use os.waitpid(pid, os.WEXITED)
. 为了
os.waitpid(pid, os.WEXITED)
未来发展,我将使用os.waitpid(pid, os.WEXITED)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.