in reply to Re^2: how to change process & thread priority on Win32 ?
in thread how to change process & thread priority on Win32 ?
For future reference please use code tags in your posts.$obj->SetPriorityClass(THREAD_PRIORITY_HIGHEST); # or THREAD_PRIORITY_ +LOWEST or whatever
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: how to change process & thread priority on Win32 ?
by rbutcher (Beadle) on Dec 08, 2005 at 06:48 UTC | |
The values my C acquaintance gave me are :- I use the following code :- It returns code 0 (failure) for HIGHEST and NORMAL, 1 (OK) for BELOW, IDLE, LOWEST, but does not in fact set the Thread Priority. In fact it will only set Process Priority, and only when I give it correct values as detailed above. E.g. sets Process Priority to normal as it should. Conclusion : SetPriority does not seem able to set Thread Priority. Or am I missing something ? How do I tell it that it's a Thread Priority I'm trying to change rather than a Process Priority ? Why would the Pod text describe Thread Priority values if the routine won't use them ? | [reply] [d/l] [select] |
by BrowserUk (Patriarch) on Dec 08, 2005 at 09:17 UTC | |
You are correct. The calls in Win32::Process are Process specific and have nothing to do with threads at all. To set thread priorities you will need to use Win32::API to gain access to SetThreadPriority(). That is easy enough to do, but there is a problem. In order to use that call, you will need a thread handle. Unfortunately, the tid returned by threads->tid() is not a native thread handle, but rather a Perl internal identifier, and there is no provision for obtaining the former from the latter. However, there is a native API that will return the handle for the currently running thread GetCurrentThread() and you can get at that through Win32::API. Provided that you only want each thread to be able to alter it's own priority, that works nicely, but if you want a central thread to be able to adjust the priorities of other threads, then you will have to set up a mapping between threads->tids and Win32 Thread handles. One way to do that would be to create a shared hash and have each of your threads query it's own thread handle and save it in the hash keyed by their threads->tid, or perhaps something that identifies the thread by what it does. Unfortunately, the handle returned by GetCurrentThread() is not a real handle, but a psuedo-handle (-2) that can only be used within that thread. To be able to get a handle usable by other threads, it is necessary to duplicate the handle using DuplicateHandle() (D'uh:). Putting that all together, you arrive at something like this. The following snippet sets 7 threads running, has them query their thread handles, duplicate them for use in other threads and set up the tid->handle mapping in a shared hash. The main thread then sets their priorities, one at each of those possible, before setting the $go flag and allowing them to run for 10 seconds. Once they get the off, each thread attempts to relinguish its timeslice 2 million times, counting them as it does so; before printing out its priority and the count of timeslices it was allocated before it reached 2 million or ran out of time. It shows that higher priority threads will starve lower ones (almost) completely of cpu whilst they are able to run, hence the lower priority threads show almost no activity. Output
However, if you make the sleep in the main thread loop 1 millisecond instead of 0, then during that 1 millisecond, lower priority threads are able to run, with the result that all threads receive an almost equal share of the processor.
As all the threads are sleeping most of the time, there are only a few occasions when a higher priority thread is eligible to run at the same time as a lower one and therefore usurps its timeslice. The code
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
by rbutcher (Beadle) on Dec 10, 2005 at 00:16 UTC | |
Value 1 is returned by Import, which I understand means OK. But value 0 is returned by SetThreadPriority. I tried using literals of 952 for the Handle of the thread I want to change and 0, 1, -1 for thread priority. Still no luck. Am I using the wrong format for the parameters, or is the required Handle for the thread something else, not what I see in Task Manager as PID ? I think I haven't understood the relationship of Thread Handle to PID where there is only a single thread - If I use Win32::Process to dump all the process details, it shows 952 for Handle and ProcessId - is this the real internal picture or not ? Is this the issue you were describing with "if you want a central thread to be able to adjust the priorities of other threads, then you will have to set up a mapping between threads->tids and Win32 Thread handles." - i.e. with my code example can I only change the thread priority of perl itself ? thanks Rod | [reply] [d/l] |
by BrowserUk (Patriarch) on Dec 10, 2005 at 04:10 UTC | |
by rbutcher (Beadle) on Dec 10, 2005 at 06:22 UTC | |
| |
| |