我测量了psutil.Process(pid).name
的性能,结果发现它比例psutil.Process(pid).exe
慢了十倍多。因为这些函数中的最后一个需要在路径上具有不同的权限,所以我不能只从路径中提取文件名。我的问题是:psutil.Process(pid).name
是否有其他方法可以做同样的事情?
答案 0 :(得分:4)
你提到这是针对Windows的。我看了一下psutil对windows的作用。看起来像psutil.Process()。name正在使用windows工具帮助API。如果你看一下psutil的Process代码和trace .name,它会转到process_info.c中的get_name()。它循环遍历您系统上的所有pid,直到找到您正在寻找的那个。我认为这可能是toolhelp API的限制。但这就是为什么它比.exe更慢,它使用不同的API路径(正如你所指出的那样)需要额外的权限。
我想出的解决方案是使用ctypes和ctypes.windll直接调用windows ntapi。它只需要PROCESS_QUERY_INFORMATION,它与PROCESS_ALL_ACCESS:
不同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)
答案 1 :(得分:0)
自psutil 1.1.0起,此问题已修复,请参阅https://code.google.com/p/psutil/issues/detail?id=426