为什么os.kill(pid,0)返回None,虽然进程已经终止? [英] Why does os.kill(pid, 0) return None although process has terminated?

查看:905
本文介绍了为什么os.kill(pid,0)返回None,虽然进程已经终止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



正如上所示,我通过Ajax GET请求定期在Django视图中检查子进程的状态。



服务器端的Django视图



  def monitor_process )
response_data = {}

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

return HttpResponse(json.dumps(response_data),mimetype ='application / json')

客户端的Ajax调用

  var monitorProcess = function(processId){

$ .ajax({
dataType:'json',
类型:'GET',
url:'/ monitor_process /',
data:{'process_id':processId},
success:function响应){

if(response.process_status =='running'){
//只有这个分支总是执行

// ...
}

else if(response.process_status =='finished'){
//此分支从不执行

//停止检查进程状态
//定期检查由
// window.setInterval在不同的Ajax调用
clearInterval(monitorProcessId)中启动;

// ...

}
}
});
};

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

解决方案

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

  os.killpg(pgid,sig)

杀死所有的组。您可以在

  / proc /< PID> / task / 
/ pre>

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


This issue is related to this answer for one of my other questions. I was told in this answer that one can use os.kill(pid, 0) to check whether a subprocess has terminated. If it is still running, None is returned. If it has terminated, an OSError is raised. This has been working fine so far, but now I'm in a situation in which os.kill(pid, 0) still returns None although the subprocess has already terminated. The process id was 82430 and in the activity monitor on OSX I cannot find a process with this ID anymore. However, when I open a Python shell and enter os.kill(82430, 0), then it still returns None. I don't understand that.

Precisely, I check the status of the subprocess periodically in a Django view via an Ajax GET request as shown above.

Django view on server side

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

Ajax call on client side

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

                // ...

            }
        }
    });
}; 

Although the process stops and disappears in the activity monitor at some point, os.kill() apparently doesn't recognize it. Why is this the case? Thank you very much!

解决方案

it's not about python, it's more about the process itself: each running process may spawn some threads around with a different PID. if the parent is not killed properly, they stay there ("zombie threads"). They are grouped altogheter with their parent under the same ID. that's why, in python, you can use

os.killpg(pgid, sig) 

to kill all the group. You can check under

/proc/<PID>/task/ 

(where is your actual process id) for any thread spawned

这篇关于为什么os.kill(pid,0)返回None,虽然进程已经终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆