Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python psutil.Process(pid.name)的替代品_Python_Performance_Pywin32 - Fatal编程技术网

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:
子句中,以避免边缘情况下的资源泄漏。