Recent

Author Topic: Setting Priority  (Read 10166 times)

Astral

  • New Member
  • *
  • Posts: 49
Setting Priority
« on: June 29, 2009, 02:33:26 am »

I found some code for setting priority of main thread of application.  I tried putting this in my FormCreate routine, first thing.  Where do I find THandle, Get CurrentThread, SetThreadPriority, and
the constant THREAD_PRIORITY_LOWEST?  All I can find is inc files?  Is there a Pascal source module that defines these things, or should I use the inc files?  I'm not sure where to put them.

Code: [Select]

var
  MainThread : THandle;

begin
  MainThread := GetCurrentThread;
  SetThreadPriority(MainThread, THREAD_PRIORITY_LOWEST);


I've been searching for the answer to this question:

Which unit(s) do I include to get this to compile?

I want to lower the priority of my application to the Lowest setting actually, to allow me to other work during long translations.  Otherwise the program grabs nearly 100% of the CPU while it's doing its thing.

I can manually set the priority to "lowest" from the Task Manager and that works fine, but I'd like to have the program do it automatically when it starts a long running operation.

Is this easy to do in Lazarus/FPC?

I did a search for the functions used above and found them in an inc file, and I am not used to using inc files in Pascal.

I'm not sure where to put the include statement.  I'd prefer to add a unit to my "uses" list and be done with it.  I suppose an include would accomplish the same thing.

A simple example would be wonderful to clarify exactly how to do it.

I have searched on Google for examples but they all tend to give the actual calls without specifying which units are required.

Astral

  • New Member
  • *
  • Posts: 49
Re: Setting Priority
« Reply #1 on: June 29, 2009, 04:37:50 am »
Ok, I did some more searching, and I found a component called
LazThread.

I attempted to install it and it said it had to recompile Lazarus itself.

So I let it do that.  Now I have the package installed and when I include the name in the "uses" list, it still can't find it.

I wonder if there's a path I have to add, or what?

This is not a "high priority" task, just something I always wanted to do in my program, but didn't know how.  I never figured out how to do it in Delphi either.  I presume it is possible.

I want to lower the priority of my application (or the main thread thereof).  It would be "nice" to find out how.  I remember the "nice" command from "the old days".  I presume it still exists on Linux.  I'm using Windows right now, but will be porting my app to Linux when I get past the Win 32 problems and get it running well.

I suspect the Mac OSX will be another challenge down the road.

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1890
Re: Setting Priority
« Reply #2 on: June 29, 2009, 09:53:28 am »
If you want to slow down your  program, add some

Sleep(1);
and/or
Application.Processmessages

to your loops.

Setting thread priority on Linux requires higher privileges afair.

Vincent Snijders

  • Administrator
  • Hero Member
  • *
  • Posts: 2661
    • My Lazarus wiki user page
Re: Setting Priority
« Reply #3 on: June 29, 2009, 10:12:09 am »
AFAIK, you can lower the priority of the processes you own in Linux.

If you use TThread, you can try TThread.Priority. With the LazThread package, you can create a new unit with a TThread descendant.

Astral

  • New Member
  • *
  • Posts: 49
Re: Setting Priority
« Reply #4 on: June 29, 2009, 12:05:07 pm »
Thanks.  I'm ashamed to admit that a lot of object-oriented concepts fly right by me with a big whooshing noise.

I am trying to permanently lower the priority, but it's a good point that I can only lower my own priority, not raise it.  I don't want my users to have to run my program as root.  lol  It's nice to be root.

I have Application.ProcessMessages calls in all the long-running loops.  For instance when I am loading a file into the editor to be translated I load the file line by line, so I can do word wrap, which SynEdit does not do.  A long file can take a significant time to load.  I also load dictionary files in to memory using TWideStringsList from Mike Lischke's Unicode package (scarfed from the freeware version of TNTware).

But a translation can take many minutes or even hours and during that time I want to have relatively normal use of the machine for browsing, checking my email, etc.  I've noticed when my program is running at normal priority it prevents certain Java programs from running successfully, such as the jigsaw puzzle program I use as something to do while I'm waiting on my program to finish.

I will have to experiment with sleep calls.  I want my program to allow normal use of the machine while I'm running it, and setting the priority via task manager has done precisely what I wanted, without totally killing the performance of my program.  I am running Lazarus on an old Penitum 4 at 1.6 GHz with 512 MB of RAM.  I'm sure if I put it on a faster machine it would be less of a problem.

I tried including LazThread in my "uses" list for my unit.  I'm not exactly sure how to use it now.  I have to set a search path or two in the Compiler options.

I'm confused by havung to install LazThread as a package or component.  I clicked on Install and it seemed to have gone ok.

But now I am not exactly sure how to incorporate that component.  Perhaps you are telling me the answer by mentioning TThread, but I am too dense to get it.  I suspect I am close to finding the answer.

I will try the TThread idea, as soon as I can figure out how.

Thanks!

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1890
Re: Setting Priority
« Reply #5 on: June 29, 2009, 12:21:06 pm »
Maybe this works:

ThreadSetPriority(GetCurrentThreadId,-15);

At least it compiles... ;-)

Astral

  • New Member
  • *
  • Posts: 49
Re: Setting Priority
« Reply #6 on: June 30, 2009, 11:14:45 am »
Yes, it does compile!  But it didn't seem to help much.

I also go the other code (shown above) to work, and it seems to have some effect.

I was wondering how changing the priority of the main application thread in my program differs from doing it externally through Task Manager.

My program does seem to cooperate better with Firefox running a Java program like jigzone.com jigsaw puzzles ( for instance ).

However, I still have to have those Application.Process Messages in the code to get the scheme to work.

I've tried sleep calls in other programs and they don't seem to work as well as altering the priority.

Maybe someone else can benefit from my experience.
Here is what I have in there now:

Code: [Select]
interface

uses
  Classes, SysUtils, FileUtil, LResources,
  Forms, Controls, Graphics,   Dialogs,
  Menus, StdCtrls, SynEdit, ComCtrls,
  LCLType,
  JwaWinBase,
  LazThread,
...
procedure TMainForm.FormCreate(Sender: TObject);
var
  CreateStatus : Boolean;
  MainThread   : THandle;

...

begin

  MainThread := GetCurrentThreadID;
  SetThreadPriority(MainThread, THREAD_PRIORITY_LOWEST);

// Tried this, didn't seem to work as well, or maybe not at all.
//ThreadSetPriority(GetCurrentThreadId,-15);

...