Existe uma maneira de verificar se um pid corresponde a um processo válido? Estou recebendo um pid de uma fonte diferente de os.getpid()
e preciso verificar se um processo com esse pid não existe na máquina.
Eu preciso que ele esteja disponível no Unix e no Windows. Também estou verificando se o PID NÃO está em uso.
Respostas:
Enviar o sinal 0 para um pid levantará uma exceção OSError se o pid não estiver em execução e não fará nada de outra forma.
fonte
os.kill(pid, 0)
é o mesmoos.kill(pid, signal.CTRL_C_EVENT)
que pode encerrar o processo (ou falhar). Eu recebo umOSError
ondeerrno==EINVAL
quando tento isso em um subprocesso.Dê uma olhada no
psutil
módulo:Ele tem uma função chamada
pid_exists()
que você pode usar para verificar se existe um processo com o pid fornecido.Aqui está um exemplo:
Para referência:
fonte
psutil
implementapid_exists()
no POSIX . Compare com a resposta de @Giampaolo Rodolà (autor depsutil
)O código mluebke não está 100% correto; kill () também pode aumentar EPERM (acesso negado), caso em que isso obviamente significa que existe um processo. Isso deve funcionar:
(editado de acordo com os comentários de Jason R. Coombs)
Você não pode fazer isso no Windows, a menos que use pywin32, ctypes ou um módulo de extensão C. Se você concordar em depender de uma biblioteca externa, poderá usar o psutil :
fonte
As respostas envolvendo o envio de 'sinal 0' para o processo funcionarão apenas se o processo em questão pertencer ao usuário que está executando o teste . Caso contrário, você obterá um
OSError
devido às permissões , mesmo se o pid existir no sistema.Para contornar essa limitação, você pode verificar se
/proc/<pid>
existe:Isso se aplica apenas a sistemas baseados em Linux, obviamente.
fonte
PermissionError
significa que pid existe , você obtémProcessLookupError
se pid não existir.OSError
permissão devido à negada pode ser diferenciada de outras - olhando para errno ou capturando asPermissionError
/ProcessLookupError
exceções mais especializadas que derivam deOSError
. Além disso, você só obterá o erro de permissão se o processo existir. Portanto, seu exemplo é apenas um método alternativo que funciona no Linux e alguns outros Unices, mas não é mais completo do que a chamada corretaos.kill(pid, 0)
./proc
procfs só sai no Linux, nem mesmo no BSD ou OSX.No Python 3.3+, você pode usar nomes de exceção em vez de constantes errno. Versão Posix :
fonte
Procure aqui uma maneira específica do Windows de obter uma lista completa dos processos em execução com seus IDs. Seria algo como
Você pode então verificar o pid obtido nesta lista. Não tenho ideia sobre o custo de desempenho, então é melhor você verificar isso se for fazer a verificação pid com frequência.
Para * NIx, apenas use a solução do mluebke.
fonte
Com base no ntrrgc, reforcei a versão do Windows para que ele verifique o código de saída do processo e verifique as permissões:
fonte
GetExistCodeProcess
requer os direitos de acessoPROCESS_QUERY_INFORMATION
ePROCESS_QUERY_LIMITED_INFORMATION
.GetExitCodeProcess
recebe um identificador e um ponteiro e neste exemplo está recebendo umaExitCodeProcess
estrutura como segundo parâmetro quando deveria ser apenas um ponteiro.Combinando a resposta de Giampaolo Rodolà para POSIX e a minha para Windows , obtive o seguinte:
fonte
GetExitCodeProcess
e ter certeza de que ainda tem acesso.kernel32.OpenProcess
apenas não é suficiente. Como apontado aqui , "se o processo foi encerrado recentemente, ainda pode existir um pid para o identificador." Sekernel32.OpenProcess
retornar um valor diferente de zero, ainda precisamoskernel32.GetExitCodeProcess
verificar o código de saída.No Windows, você pode fazer isso desta forma:
Em primeiro lugar, neste código você tenta obter um identificador para o processo com pid fornecido. Se o identificador for válido, feche o identificador para processo e retorne True; caso contrário, você retorna False. Documentação para OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
fonte
Isso funcionará no Linux, por exemplo, se você quiser verificar se o banshee está rodando ... (o banshee é um reprodutor de música)
fonte
os.kill(pid, 0)
ou olhar/proc/{pid}
. Em vez de executar um syscall, seu código bifurca um filho, executa um shell naquele filho, o shell interpreta seu mini-script de shell supérfluo, o shell bifurca outro filho que executa pgrep e, finalmente, pgrep itera/proc
. Sua resposta não responde à pergunta postada. O OP pediu um método dado um PID. Seu método requer um nome de processo.Eu diria que use o PID para qualquer propósito que você estiver obtendo e lide com os erros normalmente. Caso contrário, é uma corrida clássica (o PID pode ser válido quando você verifica se é válido, mas vá embora um instante depois)
fonte