[fpc-devel] Threads not working in console application
Hi, I've created a while back a thread based Timer. At the time I developed the timer, I tested it in a Lazarus (LCL) GUI application and everything worked perfectly. Just tested it now and it still works fine. Today I tried to use that Timer in a Console application and a fpGUI based application and the timer doesn't work for some reason! I'm using FPC 2.2.0 under Linux. I attached a Console test project and the threadtimer.pas unit. Has anybody got any ideas as to why it doesn't work in a console app? BTW: To get the console app to continue running, I have a loop checking for a file or sleeps for 500 ms. The timer is enabled before that loop starts, so I am supposed to see output to the console. I added some debug writeln()'s to know when the time starts or stops and which events file (application loop or timer event). Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ { A basic thread based timer component. Can be used in GUI and non-GUI apps. Author: Graeme Geldenhuys } unit ThreadTimer; {$mode objfpc}{$H+} interface uses Classes; type TFPTimer = class; // forward declaration TFPTimerThread = class(TThread) private FTimer: TFPTimer; protected procedure DoExecute; procedure Execute; override; public constructor CreateTimerThread(Timer: TFPTimer); end; TFPTimer = class(TComponent) private FInterval: Integer; FPriority: TThreadPriority; FOnTimer: TNotifyEvent; FContinue: Boolean; FRunning: Boolean; FEnabled: Boolean; procedure SetEnabled(Value: Boolean ); protected procedure StartTimer; procedure StopTimer; propertyContinue: Boolean read FContinue write FContinue; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure On; procedure Off; published propertyEnabled: Boolean read FEnabled write SetEnabled; propertyInterval: Integer read FInterval write FInterval; propertyThreadPriority: TThreadPriority read FPriority write FPriority default tpNormal; propertyOnTimer: TNotifyEvent read FOnTimer write FOnTimer; end; implementation uses SysUtils; { No need to pull in the Windows unit. Also this works on all platforms. } function _GetTickCount: Cardinal; begin Result := Cardinal(Trunc(Now * 24 * 60 * 60 * 1000)); end; { TFPTimerThread } constructor TFPTimerThread.CreateTimerThread(Timer: TFPTimer); begin inherited Create(True); FTimer := Timer; FreeOnTerminate := True; end; procedure TFPTimerThread.Execute; var SleepTime: Integer; Last: Cardinal; begin while FTimer.Continue do begin Last := _GetTickCount; Synchronize(@DoExecute); SleepTime := FTimer.FInterval - (_GetTickCount - Last); if SleepTime 10 then SleepTime := 10; Sleep(SleepTime); end; end; procedure TFPTimerThread.DoExecute; begin if Assigned(FTimer.OnTimer) then FTimer.OnTimer(FTimer); end; { TFPTimer } constructor TFPTimer.Create(AOwner: TComponent); begin inherited; FPriority := tpNormal; end; destructor TFPTimer.Destroy; begin StopTimer; inherited Destroy; end; procedure TFPTimer.SetEnabled(Value: Boolean); begin if Value FEnabled then begin FEnabled := Value; if FEnabled then StartTimer else StopTimer; end; end; procedure TFPTimer.StartTimer; begin if FRunning then Exit; //== FContinue := True; if not (csDesigning in ComponentState) then begin with TFPTimerThread.CreateTimerThread(Self) do begin Priority := FPriority; Resume; end; end; FRunning := True; writeln('StartTimer');// debug line end; procedure TFPTimer.StopTimer; begin writeln('StopTimer'); // debug line FContinue := False; FRunning := False; end; procedure TFPTimer.On; begin StartTimer; end; procedure TFPTimer.Off; begin StopTimer; end; end. test.lpr Description: Binary data ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Threads not working in console application
From: Graeme Geldenhuys [EMAIL PROTECTED] Hi, I've created a while back a thread based Timer. At the time I developed the timer, I tested it in a Lazarus (LCL) GUI application and everything worked perfectly. Just tested it now and it still works fine. Today I tried to use that Timer in a Console application and a fpGUI based application and the timer doesn't work for some reason! I'm using FPC 2.2.0 under Linux. I attached a Console test project and the threadtimer.pas unit. Has anybody got any ideas as to why it doesn't work in a console app? BTW: To get the console app to continue running, I have a loop checking for a file or sleeps for 500 ms. The timer is enabled before that loop starts, so I am supposed to see output to the console. I added some debug writeln()'s to know when the time starts or stops and which events file (application loop or timer event). The thread itself works, but not Synchronize() method. You need to call CheckSynchronize inside main loop. Yury. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Threads not working in console application
On Thu, 6 Dec 2007, Graeme Geldenhuys wrote: Hi, I've created a while back a thread based Timer. At the time I developed the timer, I tested it in a Lazarus (LCL) GUI application and everything worked perfectly. Just tested it now and it still works fine. Today I tried to use that Timer in a Console application and a fpGUI based application and the timer doesn't work for some reason! I'm using FPC 2.2.0 under Linux. As far as I can see, you forget to call checksynchronize in the main thread. BTW. There is a TThreadedTimer in the FCL, based on your code. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Threads not working in console application
On 06/12/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote: As far as I can see, you forget to call checksynchronize in the main thread. Thanks Michael BTW. There is a TThreadedTimer in the FCL, based on your code. I guess it didn't make it into FPC 2.2.0 as I searched all the sources and couldn't find any such class. Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Threads not working in console application
On 06/12/2007, Yury Sidorov [EMAIL PROTECTED] wrote: The thread itself works, but not Synchronize() method. You need to call CheckSynchronize inside main loop. Ah, thanks Yury! That also means that having the main loop fire every 500ms (it was just a test for the console app), my timer cannot fire it's events in less than 500ms (eg: timer.Interval := 200). while True do begin if FileExists('killme') then break; Sleep(500); CheckSynchronize; writeln('event loop'); end; As a test, I set the main loop's Sleep() to 10ms and the app didn't even register in 'top' for CPU usage, so I guess it's ok to set sleep() with such a small time? Not that I intend to use the Timer interval for 500ms though. I'll read up no CheckSyncronize to get a better understanding of this... Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Threads not working in console application
On Thu, 6 Dec 2007, Graeme Geldenhuys wrote: On 06/12/2007, Michael Van Canneyt [EMAIL PROTECTED] wrote: As far as I can see, you forget to call checksynchronize in the main thread. Thanks Michael BTW. There is a TThreadedTimer in the FCL, based on your code. I guess it didn't make it into FPC 2.2.0 as I searched all the sources and couldn't find any such class. Hm. It should be. Unit fptimer.pp. Of course, if you used the TThreadedTimer name, it won't work. look for TFPThreadedTimerDriver. I generalized the architecture a bit. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel