파이썬에 pid가 주어진 프로세스가 있는지 확인하는 방법은?
pid가 유효한 프로세스에 해당하는지 확인할 수 있는 방법이 있습니까?다른 정보원으로부터 피드를 받고 있습니다.os.getpid()
그리고 그 pid를 가진 프로세스가 기계에 존재하지 않는지 확인해야 합니다.
유닉스와 윈도우에서 사용할 수 있어야 합니다.PID가 사용되고 있지 않은지도 확인 중입니다.
신호 0을 pid로 전송하면 pid가 실행되고 있지 않으면 OS 오류 예외가 발생하고, 그렇지 않으면 아무 것도 수행하지 않습니다.
import os
def check_pid(pid):
""" Check For the existence of a unix pid. """
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
모듈을 살펴봅니다.
psutil(python 시스템 및 프로세스 유틸리티)은 Python에서 실행 중인 프로세스 및 시스템 사용률(CPU, 메모리, 디스크, 네트워크)에 대한 정보를 검색하기 위한 크로스 플랫폼 라이브러리입니다. [...] 현재 32비트 및 64비트 아키텍처인 Linux, Windows, OSX, FreeBSD 및 Sun Solaris를 지원하며 Python 버전은 2.6에서 3.4(Python 사용자)입니다.2.4 및 2.5는 2.1.3 버전을 사용할 수 있습니다.PyPy도 작동하는 것으로 알려져 있습니다.
라는 기능이 있습니다.pid_exists()
지정된 pid를 가진 프로세스가 존재하는지 확인하는 데 사용할 수 있습니다.
예는 다음과 같습니다.
import psutil
pid = 12345
if psutil.pid_exists(pid):
print("a process with pid %d exists" % pid)
else:
print("a process with pid %d does not exist" % pid)
참고용:
- https://pypi.python.org/pypi/psutil
- https://github.com/giampaolo/psutil
- http://pythonhosted.org/psutil/ #psutil.pid_
mluebke 코드는 100% 정확하지 않습니다. kill()은 또한 EPERM(액세스 거부)을 상승시킬 수 있습니다. 이는 명백히 프로세스가 존재한다는 것을 의미합니다.이것은 효과가 있어야 합니다.
(제이슨 R에 따라 편집됨).쿰스 코멘트)
import errno
import os
def pid_exists(pid):
"""Check whether pid exists in the current process table.
UNIX only.
"""
if pid < 0:
return False
if pid == 0:
# According to "man 2 kill" PID 0 refers to every process
# in the process group of the calling process.
# On certain systems 0 is a valid PID but we have no way
# to know that in a portable fashion.
raise ValueError('invalid PID 0')
try:
os.kill(pid, 0)
except OSError as err:
if err.errno == errno.ESRCH:
# ESRCH == No such process
return False
elif err.errno == errno.EPERM:
# EPERM clearly means there's a process to deny access to
return True
else:
# According to "man 2 kill" possible error values are
# (EINVAL, EPERM, ESRCH)
raise
else:
return True
pywin32, ctype 또는 C 확장 모듈을 사용하지 않는 한 Windows에서는 이 작업을 수행할 수 없습니다.외부 lib에 의존해서 괜찮다면 psutil을 사용할 수 있습니다.
>>> import psutil
>>> psutil.pid_exists(2353)
True
해당 프로세스에 '신호 0'을 보내는 것과 관련된 답변은 테스트를 실행하는 사용자가 해당 프로세스를 소유하고 있는 경우에만 작동합니다.그렇지 않으면 당신은 그들을 얻게 될 것입니다.OSError
시스템에 pid가 존재하더라도 권한 때문에.
이 제한을 우회하기 위해 다음을 확인할 수 있습니다./proc/<pid>
존재:
import os
def is_running(pid):
if os.path.isdir('/proc/{}'.format(pid)):
return True
return False
이것은 명백히 리눅스 기반 시스템에만 적용됩니다.
Python 3.3+에서는 오류 상수 대신 예외 이름을 사용할 수 있습니다.Posix 버전:
import os
def pid_exists(pid):
if pid < 0: return False #NOTE: pid == 0 returns True
try:
os.kill(pid, 0)
except ProcessLookupError: # errno.ESRCH
return False # No such process
except PermissionError: # errno.EPERM
return True # Operation not permitted (i.e., process exists)
else:
return True # no error, we can send a signal to the process
실행 중인 프로세스의 전체 목록을 ID로 가져올 수 있는 윈도우별 방법을 여기에서 확인해 보십시오.그것은 마치.
from win32com.client import GetObject
def get_proclist():
WMI = GetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
return [process.Properties_('ProcessID').Value for process in processes]
그런 다음 이 목록에 대해 pid를 확인할 수 있습니다.성능비에 대해서는 전혀 모르니 자주 검증하실 거면 확인해보시는 게 좋겠습니다.
*NIX의 경우 mluebke의 솔루션을 사용하면 됩니다.
ntrrgcs를 기반으로 윈도우 버전을 강화하여 프로세스 종료 코드를 확인하고 권한을 확인합니다.
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
if os.name == 'posix':
import errno
if pid < 0:
return False
try:
os.kill(pid, 0)
except OSError as e:
return e.errno == errno.EPERM
else:
return True
else:
import ctypes
kernel32 = ctypes.windll.kernel32
HANDLE = ctypes.c_void_p
DWORD = ctypes.c_ulong
LPDWORD = ctypes.POINTER(DWORD)
class ExitCodeProcess(ctypes.Structure):
_fields_ = [ ('hProcess', HANDLE),
('lpExitCode', LPDWORD)]
SYNCHRONIZE = 0x100000
process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
if not process:
return False
ec = ExitCodeProcess()
out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec))
if not out:
err = kernel32.GetLastError()
if kernel32.GetLastError() == 5:
# Access is denied.
logging.warning("Access is denied to get pid info.")
kernel32.CloseHandle(process)
return False
elif bool(ec.lpExitCode):
# print ec.lpExitCode.contents
# There is an exist code, it quit
kernel32.CloseHandle(process)
return False
# No exit code, it's running.
kernel32.CloseHandle(process)
return True
POSIX에 대한 Giampaolo Rodola의 답변과 Windows에 대한 제 답변을 종합하면 다음과 같습니다.
import os
if os.name == 'posix':
def pid_exists(pid):
"""Check whether pid exists in the current process table."""
import errno
if pid < 0:
return False
try:
os.kill(pid, 0)
except OSError as e:
return e.errno == errno.EPERM
else:
return True
else:
def pid_exists(pid):
import ctypes
kernel32 = ctypes.windll.kernel32
SYNCHRONIZE = 0x100000
process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid)
if process != 0:
kernel32.CloseHandle(process)
return True
else:
return False
Windows(윈도우)에서는 다음과 같은 방법으로 작업할 수 있습니다.
import ctypes
PROCESS_QUERY_INFROMATION = 0x1000
def checkPid(pid):
processHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFROMATION, 0,pid)
if processHandle == 0:
return False
else:
ctypes.windll.kernel32.CloseHandle(processHandle)
return True
우선 이 코드에서 당신은 pid가 주어진 프로세스에 대한 핸들을 잡으려고 시도합니다.핸들이 유효하면 핸들을 닫고 True를 반환합니다. 그렇지 않으면 False를 반환합니다.오픈프로세스 문서 : https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
예를 들어, banshee가 실행 중인지 확인하려면 Linux에서 작동합니다.(bans는 음악 연주자입니다)
import subprocess
def running_process(process):
"check if process is running. < process > is the name of the process."
proc = subprocess.Popen(["if pgrep " + process + " >/dev/null 2>&1; then echo 'True'; else echo 'False'; fi"], stdout=subprocess.PIPE, shell=True)
(Process_Existance, err) = proc.communicate()
return Process_Existance
# use the function
print running_process("banshee")
다음 코드는 Linux와 Windows에서 모두 작동하며 외부 모듈에 따라 작동하지 않습니다.
import os
import subprocess
import platform
import re
def pid_alive(pid:int):
""" Check For whether a pid is alive """
system = platform.uname().system
if re.search('Linux', system, re.IGNORECASE):
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
elif re.search('Windows', system, re.IGNORECASE):
out = subprocess.check_output(["tasklist","/fi",f"PID eq {pid}"]).strip()
# b'INFO: No tasks are running which match the specified criteria.'
if re.search(b'No tasks', out, re.IGNORECASE):
return False
else:
return True
else:
raise RuntimeError(f"unsupported system={system}")
필요한 경우 쉽게 개선할 수 있습니다.
- 기타 플랫폼
- 타국어
이 솔루션은 윈도우와 리눅스 모두에서 잘 작동하는 것 같습니다.저는 가성낭종을 이용해서 확인했습니다.
import psutil
import subprocess
import os
p = subprocess.Popen(['python', self.evaluation_script],stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
pid = p.pid
def __check_process_running__(self,p):
if p is not None:
poll = p.poll()
if poll == None:
return True
return False
def __check_PID_running__(self,pid):
"""
Checks if a pid is still running (UNIX works, windows we'll see)
Inputs:
pid - process id
returns:
True if running, False if not
"""
if (platform.system() == 'Linux'):
try:
os.kill(pid, 0)
if pid<0: # In case code terminates
return False
except OSError:
return False
else:
return True
elif (platform.system() == 'Windows'):
return pid in (p.pid for p in psutil.process_iter())
Windows의 또 다른 옵션은 pywin32 패키지를 통해서입니다.
pid in win32process.EnumProcesses()
win32 과정.EnumProcesses()는 현재 실행 중인 프로세스의 PID를 반환합니다.
다양한 솔루션을 시도한 후 psutil에 의존하는 것이 PID가 존재하는지 정확하게 말할 수 있는 OS에 구애받지 않는 최선의 방법이었습니다.위에서 제시한 바와 같이,psutil.pid_exists(pid)
의도한 대로 작동하지만 단점은 오래된 프로세스 ID와 최근에 종료된 프로세스를 포함한다는 것입니다.
해결책:프로세스 ID가 존재하는지, 현재 실행 중인지 확인합니다.
import psutil
def process_active(pid: int or str) -> bool:
try:
process = psutil.Process(pid)
except psutil.Error as error: # includes NoSuchProcess error
return False
if psutil.pid_exists(pid) and process.status() == psutil.STATUS_RUNNING:
return True
저는 PID를 어떤 목적을 위해서라도 사용하고 오류를 깔끔하게 처리하고 싶습니다.그렇지 않으면 클래식 레이스입니다(PID는 유효 여부를 확인하면 유효할 수 있지만, 잠시 후에 사라짐).
언급URL : https://stackoverflow.com/questions/568271/how-to-check-if-there-exists-a-process-with-a-given-pid-in-python
'programing' 카테고리의 다른 글
Google 페이지다운 각도JS지시 (0) | 2023.10.16 |
---|---|
ASP에서 기본 인증.NET MVC 5 (0) | 2023.10.16 |
Express에 MariaDB 연결JS 액세스 거부 암호 오류 없음 (0) | 2023.10.16 |
타임스탬프를 사용한 일별 MySQL 그룹 결과 (0) | 2023.10.16 |
크롬에서 낙하 이벤트가 발생하지 않음 (0) | 2023.10.16 |