in reply to Re^6: how to change process & thread priority on Win32 ?
in thread how to change process & thread priority on Win32 ?
Many thanks for this excellent explanation !
Thanks, but apparently not so good as you seem to have misunderstood it. Don't feel bad about that, it probably reflects more on my explanation than anything else. I'll try to correct that here.
PID == Process IDentifier. These are the values you see in the Task Manager. They are not the same as TID (Thread identifiers), nor are they either process or thread handles. You cannot use SetThreadPriority() to affect a processes priority.
Each process consists of one or more threads. Each process has a PID. Each thread within a process has a TID . Each PID is (at any given time) unique within the system. Ie. No two running processes will have the same PID. TIDs are unique within their process. That is, each threaded process will have a TID==0 (zero), and any process that has more than one thread will have a TID==1 (unless it has already terminated); and so on.
Update: The above stuck sentence is true only for TIDs returned by Perl's threads module! Which are not the same as Win32 native TIDS, which are unique within the system at any given time.
Process and thread handles are required to use the SetPriorityClass() and SetThreadPriority() APIs respectively. And you must have the correct type for each call, and handles are different from IDs.
IDs identify a particular instance of a process(within the system) or thread (within its process).
Handles are created as required for a particular use. They 'point', (in a loose sense of the term), to a given process or thread, but they also carry with them a bunch of other information, like security privileges, access rights and inheritability flags. A handle of either type can only be used within the process for which it is created, and for the purpose (thread or process) for which it is created. If you obtain a handle within one process, you cannot 'pass' it to another process and use it--except if you use DuplicateHandle() to duplicate an existing handle within one process specifically for another process.
Indeed, having duplicated a handle in one process for use in another, the duplicate is unusable within the process that created it. It must be passed to another process, and only the process for which it was duplicated, before it can be used.
All of which may be more than you wished to know, but it is necessary background information for the answer to your real question. Which, going by the code snippet you've posted above, is nothing at all to do with "threads", despite the title of your original post.
What you appear to be wanting to do, is to change the priority of a process, via it's PID (as listed in the Task Manager), from a separate process, namely a Perl script.
The good news is that, if all you want to do is change the process priority of an existing process, then Win32::Process provides access to the calls required without your needing to use Win32::API. Which means that martos posts do indeed tell you how to do this, albeit that it is completely at odds with the title of your OP.
In a nutshell, to do this you need to a) obtain a handle to the process who's priority you wish to change; b) call SetPriorityClass(). Win32::Process gives you direct access to the calls required to do both. See the snippet below.
However, I think I see from whence your confusion stems. There are two sets of 'priority' related constants exported by Win32::Process. The *PRIORITY_CLASS set and the THREAD_PRIORITY_* set.
And whilst they seem to be accepted by the module, and I get no errors from the OS when I use them, they do not appear to have any affect on the target process whatsoever.
I did get the impression from reading the MSDN docs that it might be the case that using the THREAD_PRIORITY_* constants in conjunction with SetPriorityClass() (against the process), might:
But this does not appear to be the case according to my tests. Maybe it was once true and isn't on my version of the OS. There are now two new PRIORITY_CLASS constants that the module does not export (ABOVE/BELOW_NORMAL), as these were not available when the module was written.
Basically, there appears to be no good reason that I can divine for why the THREAD_PRIORITY_* constants are exported by Win32::Process. As far as I can tell, there are no calls within that module capable of making use of them. It would probably be better if they were removed.
Here's a snippet that allows you to set the priority class of an existing process to any of the 4 (6, depending on the age of your version) priority classes:
realtime|high(|above)|normal(|below)|idle.
It could really use the addition of code to look up the process by name and retrieve its PID, but there are several snippets around the site for doing that.
#! perl -slw use strict; use Win32::Process; my %priorityClasses = ( realtime => REALTIME_PRIORITY_CLASS, high => HIGH_PRIORITY_CLASS, above => 0x00008000, ## ABOVE_NORMAL_PRIORITY_C +LASS (Not NT/95/96/ME). normal => NORMAL_PRIORITY_CLASS, below => 0x00004000, ## BELOW_NORMAL_PRIORITY_C +LASS (Not NT/95/96/ME). idle => IDLE_PRIORITY_CLASS, ); my %priority2class = reverse %priorityClasses; my( $pid, $priorityClass ) = @ARGV; $priorityClass = lc $priorityClass; die 'Priority class must be specified as [realtime|above|normal|below| +idle]' unless exists $priorityClasses{ $priorityClass }; my( $OS, $major, $minor, $build, $id ) = Win32::GetOSVersion(); die "Priority class $priorityClass not available on $OS" if $priorityClass eq 'above' or $priorityClass eq 'below' and $major < 5; my( $hProcess, $class ); Win32::Process::Open( $hProcess, $pid, 0 ) or die $^E; $hProcess->GetPriorityClass( $class ); print "Process $pid had priority class: ", $priority2class{ $class }; $hProcess->SetPriorityClass( $priorityClasses{ $priorityClass } ) or d +ie $^E; $hProcess->GetPriorityClass( $class ); print "Process $pid now has priority class: ", $priority2class{ $class + }; __END__ P:\test>SetPriority.pl 1892 high Process 1892 had priority class: normal Process 1892 now has priority class: high P:\test>SetPriority.pl 1892 normal Process 1892 had priority class: high Process 1892 now has priority class: normal
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^8: how to change process & thread priority on Win32 ?
by rbutcher (Beadle) on Dec 10, 2005 at 06:22 UTC | |
by BrowserUk (Patriarch) on Dec 10, 2005 at 08:32 UTC | |
by rbutcher (Beadle) on Dec 11, 2005 at 09:26 UTC | |
by BrowserUk (Patriarch) on Dec 11, 2005 at 09:47 UTC | |
by rbutcher (Beadle) on Dec 12, 2005 at 09:47 UTC | |
| |
by BrowserUk (Patriarch) on Dec 11, 2005 at 10:08 UTC |