为什么os.kill(pid,0)返回None,尽管进程已终止?

pem*_*ahl 4 python django

这个问题与我的其他一个问题的答案有关.在这个答案中我被告知可以os.kill(pid, 0)用来检查子进程是否已经终止.如果它仍在运行,None则返回.如果它已经终止,OSError则会引发一个.到目前为止,这一直在正常工作,但现在我处于一种os.kill(pid, 0)仍然会返回的情况,None尽管子进程已经终止.进程ID为82430,在OSX上的活动监视器中,我找不到具有此ID的进程了.但是,当我打开Python shell并输入时os.kill(82430, 0),它仍会返回None.我不明白.

确切地说,我通过Ajax GET请求在Django视图中定期检查子进程的状态,如上所示.

Django在服务器端查看

def monitor_process(request):
    response_data = {}

    try:
        os.kill(int(request.GET['process_id']), 0)
        response_data['process_status'] = 'running'
    except OSError:
        response_data['process_status'] = 'finished'

    return HttpResponse(json.dumps(response_data), mimetype='application/json')
Run Code Online (Sandbox Code Playgroud)

Ajax在客户端调用

var monitorProcess = function(processId) {

    $.ajax({
        dataType: 'json',
        type: 'GET',
        url: '/monitor_process/',
        data: {'process_id': processId},
        success: function(response) {

            if (response.process_status == 'running') {
                // Only this branch is always executed

                // ...
            }

            else if (response.process_status == 'finished') {
                // This branch never gets executed

                // Stop checking for process status
                // The periodic check was started by 
                // window.setInterval in a different Ajax call
                clearInterval(monitorProcessId);

                // ...

            }
        }
    });
}; 
Run Code Online (Sandbox Code Playgroud)

虽然过程在某个时刻停止并消失在活动监视器中,但os.kill()显然无法识别它.为什么会这样?非常感谢你!

Sam*_*zzo 5

它不是关于python,它更多的是关于进程本身:每个运行进程可能会产生一些具有不同PID的线程.如果父母没有被正确杀死,他们会留在那里("僵尸线程").它们被分组为altogheter,其父级具有相同的ID.这就是为什么,在python中,你可以使用

os.killpg(pgid, sig) 
Run Code Online (Sandbox Code Playgroud)

杀死所有的团体.你可以检查下

/proc/<PID>/task/ 
Run Code Online (Sandbox Code Playgroud)

(对于生成的任何线程,您的实际进程ID在哪里)