EnumProcesses() vs CreateToolhelp32Snapshot()
I was wonderi开发者_JAVA百科ng if there are any differences - mostly performance wise - between the two Win32 API functions EnumProcesses() and CreateToolhelp32Snapshot() for enumerating all active processes and loaded modules. Or if one is better than the other to use and why.
Here are results from few functions:
- EnumProcesses: 16 msec, 207 processes
- CreateToolhelp32Snapshot: 141 msec (16 msec), 207 processes
- WTSEnumerateProcesses: 16 msec, 207 processes
- WTSEnumerateProcessesEx(WTS_CURRENT_SESSION): 16 msec, 98 processes
- WTSEnumerateProcessesEx(WTS_ANY_SESSION): 16 msec, 207 processes
Machine is running Windows 8 with UAC enabled, user is not elevated (e.g. have no access to system processes). Main process is 32-bit, machine is 64-bit, so plenty of 64-bit processes around. There are: session 0 for system, session 1 for current console user, session 2 for another fast-switch user. 207 processes in total (these are both 32- and 64-bit, including pseudo "system" process) - 207 is also confirmed by Process Explorer. Among these 207 processes: 23 processes are for session 2, 98 processes - for session 1, and remaining - for session 0.
Results are for cycle of 10 single function call. They are 100% reproducible on each run.
For CreateToolhelp32Snapshot the main result is call of CreateToolhelp32Snapshot itself, and second result (in brackets) is cycle with First/Next.
I think people confuse "enumerate all processes" (get PIDs) and "get name of process/exe". The first one ("enumerate") has no issues with x32/x64 cross-bitness whatsoever. But the latter one ("get name") does have issues - not every method will work across x32/x64.
I think they are pretty much the same in terms of performance (and results) as they both call the same underlying NT API, though CreateToolhelp32Snapshot() may have a slight overhead as it creates a section object and copies all the information to it whereas EnumProcesses()/EnumProcessModules() works directly with user-supplied buffers. The difference is probably negligible in real world performance, though.
I slightly prefer EnumProcesses() as it is (IMO) a simpler API to use, but CreateToolhelp32Snapshot() returns more information if you need it. The only downside to EnumProcesses() is that you are supposed to call it in a loop as you may not have allocated a large enough buffer; CreateToolhelp32Snapshot() takes care of the buffer management for you. In practice I just allocate a buffer on the stack large enough to hold 1024 process ids or module handles; so far I have not come across a system where either of these limits was even remotely close to being reached. Of course we said the same thing about MAX_PATH not so long ago and now we are running into problems with that...
I don’t remember exactly, but unlike CreateToolhelp32Snapshot(), EnumProcesses() has one of two or both limitations: 1. Doesn’t enumerate 64-bit processes if called from 32-bit process on x64 OS. 2. Doesn’t enumerate elevated processes on Vista and Win7.
CreateToolhelp32Snapshot FTW. EnumProcesses doesnt enumerate all system processes like all instances of svchost.exe at least on Win XP.
IMO the key difference is in priviledges requirements. I've seen cases in which EnumProcesses()
would fail, but CreateToolhelp32Snapshot()
ran perfectly well.
So once I needed to write code that would detect a certain process on a system and react appropriately. I wrote it using EnumProcesses()
and it worked fine on my machine, but not on testers' machines. I just rewrote it with CreateToolhelp32Snapshot()
and I've never heard of any problems with it anymore.
精彩评论