Python psutil.Process(pid.name)的替代品
我已经测量了Python psutil.Process(pid.name)的替代品,python,performance,pywin32,Python,Performance,Pywin32,我已经测量了psutil.Process(pid).name的性能,结果表明它比例如psutil.Process(pid).exe慢十倍多。因为最后一个函数对路径要求不同的权限,所以我不能仅仅从路径中提取文件名。我的问题是:psutil.Process(pid.name)是否有替代品,它也有相同的功能?您提到的这是针对windows的。我看了一下psutil对windows的作用。看起来psutil.Process().name正在使用windows工具帮助API。如果您查看psutil的进程代
psutil.Process(pid).name的性能,结果表明它比例如psutil.Process(pid).exe
慢十倍多。因为最后一个函数对路径要求不同的权限,所以我不能仅仅从路径中提取文件名。我的问题是:psutil.Process(pid.name)是否有替代品,它也有相同的功能?您提到的这是针对windows的。我看了一下psutil对windows的作用。看起来psutil.Process().name正在使用windows工具帮助API。如果您查看psutil的进程代码和trace.name,它将进入。它在系统上的所有PID中循环,直到找到您要查找的PID为止。我认为这可能是ToolHelpAPI的一个限制。但这就是为什么它比使用不同API路径的.exe慢的原因,正如您所指出的,它需要额外的权限
我提出的解决方案是使用ctypes和ctypes.windell直接调用windows ntapi。它只需要进程\查询\信息,与进程\全部\访问不同:
import ctypes
import os.path
# duplicate the UNICODE_STRING structure from the windows API
class UNICODE_STRING(ctypes.Structure):
_fields_ = [
('Length', ctypes.c_short),
('MaximumLength', ctypes.c_short),
('Buffer', ctypes.c_wchar_p)
]
# args
pid = 8000 # put your pid here
# define some constants; from windows API reference
MAX_TOTAL_PATH_CHARS = 32767
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_IMAGE_FILE_NAME = 27
# open handles
ntdll = ctypes.windll.LoadLibrary('ntdll.dll')
process = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION,
False, pid)
# allocate memory
buflen = (((MAX_TOTAL_PATH_CHARS + 1) * ctypes.sizeof(ctypes.c_wchar)) +
ctypes.sizeof(UNICODE_STRING))
buffer = ctypes.c_char_p(' ' * buflen)
# query process image filename and parse for process "name"
ntdll.NtQueryInformationProcess(process, PROCESS_IMAGE_FILE_NAME, buffer,
buflen, None)
pustr = ctypes.cast(buffer, ctypes.POINTER(UNICODE_STRING))
print os.path.split(pustr.contents.Buffer)[-1]
# cleanup
ctypes.windll.kernel32.CloseHandle(process)
ctypes.windll.kernel32.FreeLibrary(ntdll._handle)
从psutil 1.1.0开始,此问题已得到修复,请参阅psutil库没有那么大。其中唯一有用的其他方法是Process(pid).cmdline(如果cmdline[0]是exe),但我猜它与exe函数具有相同的访问限制。您是否正在寻找一种非psutil方式来实现此目的?如果是,你的操作系统是什么?您总是可以为您的特定操作系统找到一种更快的方法,并重写psutil的名称函数。如果这是对psutil库的请求,您可以在项目上提交问题。我的操作系统是Windows。我可能会提交一个请求,但最好已经有了一个解决方案。告诉我们您的确切操作系统版本,包括SP和patchlevel,以及您的Python版本。另外,张贴你的计时数字。我会很快调查这一点,如果它起作用,那么你是一个和蔼可亲的人!也许你想把代码贡献给psutil?我可以确认这是可行的,比psutil的“name”方法快10倍左右。非常感谢。这太棒了。我一直在寻找一种无需昂贵的进程分叉(例如,解析tlist.exe
output)即可检索Windows进程元数据的纯Python解决方案。这肯定要花很长时间才能拼凑起来!好极了。也就是说。。。理想情况下,清理应该嵌入try:
块的finally:
子句中,以避免边缘情况下的资源泄漏。