python - psutil 总是返回 pid 存在

标签 python linux macos flask psutil

我有 Flask 应用程序,它公开了 API,可以在后台运行应用程序,稍后可以通过指定 PID 终止它。但是,出于单元测试目的,在终止 PID 并使用 psutil.pid_exists(pid) 检查 PID 是否被终止后,它似乎总是返回 true。我已手动检查 PID 不存在并在不同的 python 控制台上运行 psutil.pid_exists(pid) 并返回 true。这导致我的测试失败。

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

在我的测试中:

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))

如果有任何不同,我会在 OSX 上运行。

更新: 我尝试在我的构建服务器 (Ubuntu 14.04) 上运行测试,但测试失败。

这是我的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)

和我的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:])

我添加了一个简单的脚本来演示这一点。 https://github.com/shulhi/kill-pid/tree/master

最佳答案

终止正在运行的进程需要时间。在这种情况下,它是一个子进程,所以 os.wait()或其变体之一将确切知道要等待多长时间。为了面向 future ,我会使用 os.waitpid(pid, os.WEXITED) .

关于python - psutil 总是返回 pid 存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29911247/

相关文章:

python - 从一系列列表创建一个 Pandas DataFrame

python - Pycuda 编译错误

python - 在 BranchPython Operator 之后跳过 Airflow 2.0 任务

linux - 我们可以使用 keepalived 将 cpp 应用程序作为 HA 吗?

linux - 包含 LAMP PHP 路径

java - JAR Bundler 使用 OSXAdapter 导致应用程序滞后或终止

python - 如何在数据框中使用 word_tokenize

linux - 将构建后行写入 makefile

xcode - 在 AppleScriptObjC 中从面板制作工作表

c++ - C++、Mac OS X 10.6.8 中的串口问题