Recent

Author Topic: sleep alternative  (Read 958 times)

toby

  • Sr. Member
  • ****
  • Posts: 282
sleep alternative
« on: July 02, 2026, 02:26:07 am »
i've been searching for a timer that will not hang the program like sleep does
i

Fibonacci

  • Hero Member
  • *****
  • Posts: 1029
  • Behold, I bring salvation - FPC Unleashed
Re: sleep alternative
« Reply #1 on: July 02, 2026, 02:42:49 am »
GUI LCL? Threads.

Console? Well, threads too, but...

Code: Pascal  [Select][+][-]
  1. function nosleep(timeout: integer): PRTLEvent;
  2. begin
  3.   result := RTLEventCreate;
  4.   RTLEventWaitFor(result, timeout);
  5.   RTLEventDestroy(result);
  6. end;
  7.  
  8. begin
  9.   writeln('no sleep');
  10.   nosleep(2500);
  11.   writeln('waited 2.5 secs');
  12.   readln;
  13. end.
FPC Unleashed: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

440bx

  • Hero Member
  • *****
  • Posts: 6556
Re: sleep alternative
« Reply #2 on: July 02, 2026, 02:57:43 am »
i've been searching for a timer that will not hang the program like sleep does
If you're using Windows and you're pumping messages in a GUI program, you don't need to do anything, the message pump will not return until there is a message to be processed, your process was put to "sleep" automatically by Windows.

Sleep is the right thing to use in a non-GUI thread that is a CPU hog, e.g, some thread that may crunch numbers for a noticeable amount of time (more than a couple of seconds), calling sleep(1), relinquishes the processor for other threads to use and contributes to the system's smooth operation.   A non-GUI thread may be present in a GUI app just as it can in a CLI app.

HTH.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

mas steindorff

  • Hero Member
  • *****
  • Posts: 603
Re: sleep alternative
« Reply #3 on: July 02, 2026, 04:06:57 am »
TTimer ... ??
set the interval, callback function  and enable. I use it in non visible units too (.create) but without a parent you'll need to free it
 
windows 10 &11, Ubuntu 21+ IDE 3.4 general releases

Thaddy

  • Hero Member
  • *****
  • Posts: 19433
  • Glad to be alive.
Re: sleep alternative
« Reply #4 on: July 02, 2026, 07:13:52 am »
Sleep does not hang the program: it merely blocks execution from a single thread.
If that happens to be the main thread....
Just use TTimer.
Or if you need a non-blocking sleep? Why?? (needs trunk):
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses sysutils,classes;
  3. var
  4.   a:TThread;
  5. begin
  6.   // non-blocking sleep
  7.   a:=TThread.ExecuteInThread(procedure
  8.                              begin
  9.                                sleep(2500);
  10.                                writeln('slept for 2,5 seconds');
  11.                              end);
  12.   // perform tasks in the main thread here:
  13.   //...............ladida...................
  14.   for j := 1 to 160 do begin sleep(10);writeln(i);inc(i);end;
  15.   // but at program end the thread may still be running
  16.   // so intentionally block to be sure the program ends gracefully.                          
  17.   if not a.finished then a.Waitfor;
  18. end.
This can also be done in 3.2.x but not with an anonymous method.
Define a TThreadMethod instead and pass that as procedure pointer to TThread.ExecuteInThread :
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses sysutils,classes;
  3.  
  4. procedure Sleepy(Data:Pointer);
  5. begin
  6.   sleep(2500);
  7.   writeln('slept for 2,5 seconds');
  8. end;
  9.  
  10. var
  11.   a:TThread;
  12. begin
  13.    // non-blocking sleep
  14.    a:= TThread.ExecuteInThread(@Sleepy);
  15.   // perform tasks in the main thread here:
  16.   //...............ladida...................
  17.    for j := 1 to 160 do begin sleep(10);writeln(i);inc(i);end;
  18.  // but at program end the thread may still be running
  19.   // so intentionally block to be sure the program ends gracefully.                          
  20.   if not a.finished then a.Waitfor;
  21. end.

So maybe this is your question? A non-blocking sleep looks like this:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses sysutils,classes;
  3.  
  4. var
  5.   a:TThread;
  6.   i:integer = 0;
  7.   s:integer = 2500; // sleep value
  8. begin
  9.   // non-blocking sleep
  10.   a:= TThread.ExecuteInThread(procedure
  11.                               begin
  12.                                 Sleep(s);
  13.                                 writeln('thread slept for ',s/1000:2:1,' seconds');
  14.                               end);
  15.   // main workload                            
  16.   repeat inc(i);until a.finished;
  17.   writeln('cycles in main: ',i);
  18. end.


« Last Edit: July 02, 2026, 11:08:36 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Curt Carpenter

  • Hero Member
  • *****
  • Posts: 764
Re: sleep alternative
« Reply #5 on: July 02, 2026, 03:28:24 pm »
Depending on what you're trying to do, it may be easiest to just call GetTickCount64 from time to time.

toby

  • Sr. Member
  • ****
  • Posts: 282
Re: sleep alternative
« Reply #6 on: July 02, 2026, 08:02:00 pm »
thank you for the replies
as far as i can tell there seem to be at least 5 (maybe more ways to do this)
just for clarity i am using linux with fpc 3,3,1 and doing cli programming

i want to be  do this   
non blocking timer to wait 10 secionds -> writeln('1);
writeln('2');
---
outpui
'2'
10 seconds later '1'
---
i'd rather not use threading to do this

i had this code from the forum a long time ago but can't locate it nor searching the forum archives ffinds the relevant messages

toby

  • Sr. Member
  • ****
  • Posts: 282
Re: sleep alternative
« Reply #7 on: July 03, 2026, 03:58:30 am »
i finally found it - thanks to PascalDragon,  rvk, alpine and prodingus's coding  i got what i needed running (what a great fpc programmers they are)
[
I need to use timers for interrupts? - Free Pascal
https://forum.lazarus.freepascal.org/index.php?topic=59913.0
« Last Edit: July 03, 2026, 04:33:59 am by toby »

Thaddy

  • Hero Member
  • *****
  • Posts: 19433
  • Glad to be alive.
Re: sleep alternative
« Reply #8 on: July 03, 2026, 07:33:49 am »
If an OS allows interrupts in user space, you don't need a timer at all.
E.g. on DOS you simply write an interrupt handler.
But I guess you don't mean a hardware interrupt?
Any "programmer" that knows only one programming language is not a programmer

LeP

  • Sr. Member
  • ****
  • Posts: 437
Re: sleep alternative
« Reply #9 on: July 03, 2026, 10:31:10 am »
In delphi you can do this, very similar to @Thaddy solution, and don't need any variable explicit used, but more simple:

(protect with TCriticalSection if you call TimeCall from different threads)

Code: Pascal  [Select][+][-]
  1. procedure TimeCall(MilliSeconds: integer);
  2. begin
  3.   TTask.Run(procedure
  4.    begin
  5.      sleep (Milliseconds);
  6.      //I use TThread.Synchronize only 'cause writeln is a shared resource use by multiple concurrent thread
  7.      TThread.Synchronize(TThread.Current,
  8.        procedure
  9.        begin
  10.          writeln ('Hello, I come after + '+Milliseconds.ToString);
  11.        end);
  12.    end);
  13. end;
  14.  
  15. begin
  16.   TimeCall(500);         //This will show for THIRD
  17.   TimeCall(200);         //This will show for SECOND
  18.   TimeCall(1000);       //This will show for FIFTH
  19.   TimeCall(750);         //This will show for FOURTH
  20.   //I do other things, like show another message
  21.   writeln('I am the first');     //This will show for FIRST
  22. end;
Un Sistema per domarli, un IDE per trovarli, un codice per ghermirli e nel framework incatenarli.
An operating system to tame them, an IDE to find them, a code to catch them and in the framework chain them.

Thaddy

  • Hero Member
  • *****
  • Posts: 19433
  • Glad to be alive.
Re: sleep alternative
« Reply #10 on: July 03, 2026, 11:27:52 am »
@LeP

That also compiles in fpc trunk, although TTask from system.threading (in vcl-compat package) needs more work.
Then again, that code works in Delphi - 12.1 - unreliably/by accident.
In fpc it works even more unreliable.

Both compilers compile it, but there is an issue with the code since it deadlocks on and off in both.
That is also easily explained since the threads are not stored in outer scope, so you can't see if they are finished and then call waitfor.

Not a good solution.... I used this complete code to test and am now fixing it (for both compilers):
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$ifdef fpc}{$mode delphi}{$endif}
  3. uses sysutils, classes, syncobjs, system.threading;
  4. procedure TimeCall(MilliSeconds: integer);
  5. begin
  6.   TTask.Run(procedure
  7.    begin
  8.      sleep (Milliseconds);
  9.      //I use TThread.Synchronize only 'cause writeln is a shared resource use by multiple concurrent thread
  10.      TThread.Synchronize(TThread.Current,
  11.        procedure
  12.        begin
  13.          writeln ('Hello, I come after + '+Milliseconds.ToString);
  14.        end);
  15.    end);
  16. end;
  17.  
  18. begin
  19.   TimeCall(500);         //This will show for THIRD
  20.   TimeCall(200);         //This will show for SECOND
  21.   TimeCall(1000);       //This will show for FIFTH
  22.   TimeCall(750);         //This will show for FOURTH
  23.   //I do other things, like show another message
  24.   writeln('I am the first');     //This will show for FIRST
  25. end.
BTW, I think you don't need to worry about writeln in fpc, since it is, unlike Delphi,  fully serialized already?
When I fixed the code, I will post the proper code.(hopefully, but this is no good either  :D )
« Last Edit: July 03, 2026, 12:33:49 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Warfley

  • Hero Member
  • *****
  • Posts: 2071
Re: sleep alternative
« Reply #11 on: July 03, 2026, 12:28:31 pm »
The question is: What should be done while waiting? You say the application should not freeze?

What code should be executed and what do you expect to happen while waiting? So in the example here with Synchronize, it requires the application to run an event loop. Also you don't just "continue" after waiting, you just schedule to do something to be done later.

If you want something like async-await functions like in C#, python, Javascript, etc. you can look at my project STAX. But this is non-preemtive scheduling and has other things to consider.
Using something like interupts or signals has it's own can of worms (race conditions, deadlocks, etc.) and you are probably much better off just doing regular threading.

LeP

  • Sr. Member
  • ****
  • Posts: 437
Re: sleep alternative
« Reply #12 on: July 03, 2026, 01:15:26 pm »
@LeP
That also compiles in fpc trunk, although TTask from system.threading (in vcl-compat package) needs more work.
Then again, that code works in Delphi - 12.1 - unreliably/by accident.
In fpc it works even more unreliable.
Both compilers compile it, but there is an issue with the code since it deadlocks on and off in both.

TTask have not issue, if used correctly. Take care that Threads have FreeOnterminate set to true (in Delphi) ... this may be an issue in some situations.

Of course, we can speak about Wait, deadlocks and much other things, but this what i proposed is thinked for simple use.

Think if set an infinite value for sleep ... and it is admitted ...
Un Sistema per domarli, un IDE per trovarli, un codice per ghermirli e nel framework incatenarli.
An operating system to tame them, an IDE to find them, a code to catch them and in the framework chain them.

Thaddy

  • Hero Member
  • *****
  • Posts: 19433
  • Glad to be alive.
Re: sleep alternative
« Reply #13 on: July 03, 2026, 01:19:12 pm »
@LeP
Delphi has slightly less conflicts than fpc, but I am still investigating what the real cause is...

Any "programmer" that knows only one programming language is not a programmer

LeP

  • Sr. Member
  • ****
  • Posts: 437
Re: sleep alternative
« Reply #14 on: July 03, 2026, 03:08:06 pm »
So in the example here with Synchronize, it requires the application to run an event loop. Also you don't just "continue" after waiting, you just schedule to do something to be done later.

Synchronize was inserted only for use shared resoruce (or what I think is a shared resource, writeln).

What I show is something that you can simply call more than once: you can also for example insert a index or something else to do a specific works, call other procedures, etc ... all in async way. Of course you must take care about shared resource. But I really didn't need a lot of sync objects for my code ... every thread do a specific work and write specific resource, with a general collector so normally not use sync objects at all.

Only simple solution without any complex solution.  For sure not full and not better solution but praticall yes.
Un Sistema per domarli, un IDE per trovarli, un codice per ghermirli e nel framework incatenarli.
An operating system to tame them, an IDE to find them, a code to catch them and in the framework chain them.

 

TinyPortal © 2005-2018