MainThread := TMainPortThread.Create(True); // With the True parameter it doesn't start automatically if Assigned(MainThread.FatalException) then raise MainThread.FatalException; // Here the code initialises anything required before the threads starts executing LoopPosM := 1; MainThread.Start;
UpdateGUI:
procedure TMainPortThread.UpdateGUI; // this method is only called by Synchronize(@ShowStatus) and therefore // executed by the main thread // The main thread can access GUI elements, for example Form1.Caption. begin PulseGenForm.Shape2.Brush.Color:=clLime; if (GUIMsg='HI') then begin WriteLn('test'); end; GUIMsg := ''; end;
I can see in console, test is printed. That means this function is being called, but
the Shape2 color never changed. %)
Your method UpdateGUI should be part of your TForm. The " main thread " that can access GUI elements, for example Form1.Caption, ..., is managing the ...TForm's methods to Invalidate, Update, Paint its GUI controls (overall).
That's of course a nicer separation of concerns, but simply from the point-of-view of the execution it doesn't matter whether the code is part of the thread or the form (as long as the thread only calls it only using Synchronize or Queue).
@MarkMLl: sorry for the worry.
@GeneCode: try adding an Application.ProcessMessages at the end of your method UpdateGUI.
Side note: you only need to check FatalException after the execution of the thread, but since you're using FreeOnTerminate that's not possible anyway.
Then the problem is probably with the shape, but definitely not with the Synchronize. Does it work if you call the same code from e.g. a timer?
PulseGenForm.Shape2.Brush.Color changed the color for the next draw. But you don't draw anywhere?
PulseGenForm.Shape2.Brush.Color changed the color for the next draw. But you don't draw anywhere?
I don't need to call draw because Synchronize is supposed to run the method in main program thread, no?
@MarkMLl: sorry for the worry.Sleep(0) or Sleep(1) is often a better alternative of ProcessMessages.
@GeneCode: try adding an Application.ProcessMessages at the end of your method UpdateGUI.
Sleep(0) or Sleep(1) is often a better alternative of ProcessMessages.Just an "academic" observation. Sleep() and ProcessMessages are two very different things. A call to Sleep() has nothing to do with processing messages and, calling Sleep in a UI thread is, more often than not, a bad idea because it delays the repainting of the window.
Sleep(0) or Sleep(1) is often a better alternative of ProcessMessages.
Just an "academic" observation. Sleep() and ProcessMessages are two very different things. A call to Sleep() has nothing to do with processing messages and, calling Sleep in a UI thread is, more often than not, a bad idea because it delays the repainting of the window.
Hi
Have a look at Postmessage / Sendmessage...
From thread to main...
Regards Benny
Sleep(0) or Sleep(1) is often a better alternative of ProcessMessages.
Are you absolutely sure of that? Application.ProcessMessages specifically causes the message queue to be checked, while Sleep() simply withholds the CPU for some number of mSec.
MarkMLl
no. the only Sleep() that does that under windows is Sleep(0) which is documented as "Relinquish Process" or depending on version "relinquish timeslice"'. All other values may still be blocking. A common error and a source of many a fake news. see msdn.
https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep
Very carefully read the official documentation...
Any other value- in the context of synchronization - is usually programmer error.
This function causes a thread to relinquish the remainder of its time slice and become unrunnable for an interval based on the value of dwMilliseconds.
The idea is to have the OS manage the message passing, instead of trying to force that to happen yourself. Because you cannot force other processes to start processing their messages.
I use a small value, like 1, if I want to make sure the other processes get enough time to do their thing. In all other cases I use "WaitForObject" or something like a mutex.
One thing a programmer should keep in mind when reading documentation: documentation is the way it's supposed to work (IOW, what the programmer who wrote it dreamed) it isn't necessarily the way it _actually_ works.Yeah, sometimes docs focus too much on unimportant details, while completely missing really important things. For example for me the biggest mystery - is IDXGIOutput.FindClosestMatchingMode behavior, that seems to be wrong due to wrong treatment of DXGI_MODE_SCALING. But it isn't explained anywhere.
MS has been saying that Sleep(0) causes a thread to relinquish the remainder of its time slice, probably for ever. I've tested that on every version of Windows, probably since Win95 and, it does NOT. That is simply and provably NOT true. It didn't work that way even on NT4.
Also, as @PascalDragon indicated, Sleep() is most definitely not a substitute for processing messages. Sleep() tells the O/S not to schedule the thread for X amount of time, that's very different thing than what takes place when an application calls GetMessage.
Does it? The way I've always read the docs (and this applies to most multitasking OSes) is that it says that it re-runs the scheduling algorithm: it makes no statement as to which thread will be resumed which could very easily be the same one that called Sleep(0) if it's the best candidate.That is true but, it quickly becomes very suspicious when it is _always_ the thread that executed the Sleep(0) that gets immediately rescheduled. The results of testing Sleep(0)'s behavior indicate it _renews_ the time slice (the opposite of what the documentation states.) If the thread was truly giving up the remainder of its time slice, it could not be using 100% of a core because there would be some portion of the time slice given up in each call.
If the thread was truly giving up the remainder of its time slice, it could not be using 100% of a core because there would be some portion of the time slice given up in each call.
That is true but, it quickly becomes very suspicious when it is _always_ the thread that executed the Sleep(0) that gets immediately rescheduled. The results of testing Sleep(0)'s behavior indicate it _renews_ the time slice (the opposite of what the documentation states.) If the thread was truly giving up the remainder of its time slice, it could not be using 100% of a core because there would be some portion of the time slice given up in each call.
The problem is a call to Sleep() is, theoretically, a way to tell the CPU "don't schedule me for x amount of time" and obviously the scheduler isn't honoring that request. If it did, it would be impossible for the thread to consume 100% of a core because there would be some time given up. The fact that the CPU utilization is at 100% indicates no time is given up. Also, the O/S, most of the time, has internal housekeeping chores to take care of (such as zeroing out free pages, getting them ready to be handed to a process that will later, at some point in time, make a memory request), IOW, most of the time, the O/S has something to do other than rescheduling a thread that explicitly asked not be rescheduled until the next cycle.If the thread was truly giving up the remainder of its time slice, it could not be using 100% of a core because there would be some portion of the time slice given up in each call.
Unless there were nothing else scheduled ready to run, i.e. everything else on the system were waiting on a (kernel) timer or event.
In any event, Sleep()- with any parameter- is not equivalent to APM.Absolutely.
The problem is a call to Sleep() is, theoretically, a way to tell the CPU "don't schedule me for x amount of time" and obviously the scheduler isn't honoring that request. If it did, it would be impossible for the thread to consume 100% of a core because there would be some time given up. The fact that the CPU utilization is at 100% indicates no time is given up. Also, the O/S, most of the time, has internal housekeeping chores to take care of (such as zeroing out free pages, getting them ready to be handed to a process that will later, at some point in time, make a memory request), IOW, most of the time, the O/S has something to do other than rescheduling a thread that explicitly asked not be rescheduled until the next cycle.
But it /is/ honouring it.It isn't and the fact that it consumes 100% of a core proves it. If the thread was sleeping for _any_ amount of time, it wouldn't be consuming 100% of a core.
More significant is whether Sleep(1) reliably pauses for at least one complete mSec on a system where the tick rate is substantially slower than that e.g. every 10 mSec.The precision of the time slice given and the amount of time elapsed between time slices are a completely different matter.
It isn't and the fact that it consumes 100% of a core proves it. If the thread was sleeping for _any_ amount of time, it wouldn't be consuming 100% of a core.
It would be interesting to see how two processes on the same CPU (e.g. via CPU pinning in task manager) behave if one does the following:and the other one does:
While True do;I would guess that the second one should get a much smaller slice of the CPU time. But sadly I don't have the ability to test it right now
While True do Sleep(0);
Are you trying to tell me that your monitoring utility calculates and displays this to full floating point precision?No, that's not what I've tried to say. What I say is very simple: if the thread was giving up part of its time slice then it would NOT show a _consistent_ usage of 100% of a CPU because the thread would actually spend some time _sleeping_.
So Sleep(0) is behaving exactly as expected. It will call the scheduler and if there is no other process to schedule (because there are simply not so many tasks on a multicore system), it will immediately be rescheduled resulting in 100% CPU usage anyway.Absolutely not. Sleep tells the scheduler "don't schedule me", "don't give me clock cycles", it does not mean "put me to work", it means: for whatever the remaining amount of time I had left in the time slice, I want to do _nothing_. It tells the scheduler, NOT to schedule the thread and, if the scheduler was doing that, that thread could never use 100% of a core.
@440bx: I'm disappointed that at your age you've never learnt what "zero" means :-)At whatever your age is, I'm disappointed you haven't learned the meaning of "whatever remains of the time slice", which will very rarely be zero.
MarkMLl
Absolutely not. Sleep tells the scheduler "don't schedule me", "don't give me clock cycles", it does not mean "put me to work", it means: for whatever the remaining amount of time I had left in the time slice, I want to do _nothing_. It tells the scheduler, NOT to schedule the thread and, if the scheduler was doing that, that thread could never use 100% of a core.Let's see the documentation: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep
Sleep does NOT behave as documented. It does NOT. If it did, the thread would not consume 100% of the CPU.
A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution."If there are no other threads ready to run [...] the thread continues execution" sounds exactly as if it would result in 100% CPU usage. This behavior is fully compliant with the documentation. Also note that the doc specifically mentions that the function returns immediately, so it doesn't even go through the scheduler. It simply checks if there is another thread in queue, if yes it calls the scheduler if no it simply returns and has no effect on the scheduling behavior
Let's see the documentation: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepI'm pleased you read the documentation.QuoteA value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution."If there are no other threads ready to run [...] the thread continues execution" sounds exactly as if it would result in 100% CPU usage. This behavior is fully compliant with the documentation. Also note that the doc specifically mentions that the function returns immediately, so it doesn't even go through the scheduler. It simply checks if there is another thread in queue, if yes it calls the scheduler if no it simply returns and has no effect on the scheduling behavior
If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately.Supposedly, the thread relinquishes the remainder of its time slice (that's what the documentation says), goes into the ready state and, there is supposedly no guarantee that it will run immediately (yet, "amazingly" it does.)
Supposedly, the thread relinquishes the remainder of its time slice (that's what the documentation says), goes into the ready state and, there is supposedly no guarantee that it will run immediately (yet, "amazingly" it does.)No the scheduler doesn't, as seen in my example where I pinned the spin and the sleep process to the same CPU. It only does so if no other thread is intendet to be scheduled on the CPU. If there is another thread requiring time on that CPU the process will yield
The part that in bold is very clear. If the thread relinquished the remainder of its time slice, it could not consume 100% of CPU. The only way that can happen is if the scheduler does not put the thread to sleep for the remainder of the time slice and, worse, to consume 100% of the CPU, the scheduler has to reschedule it immediately, every time.
Too bad I can't relinquish money that way.
Yes sleep(0) will not reduce the CPU load, thats not the goal, it just yields to other processes so you don't starve them.Doesn't it strike you as a bit "unusual" that a function that is supposed to yield to other processes consumes 100% of a CPU in order to get that done ?
Yes sleep(0) will not reduce the CPU load, thats not the goal, it just yields to other processes so you don't starve them.Doesn't it strike you as a bit "unusual" that a function that is supposed to yield to other processes consumes 100% of a CPU in order to get that done ?
Just what every laptop user dreams of ... ;)
Yes sleep(0) will not reduce the CPU load, thats not the goal, it just yields to other processes so you don't starve them. If you want to actually reduce CPU usage you need to actually slow down your program (e.g. with sleep > 0)Why use sleep when you can suspend and use resume.
Why use sleep when you can suspend and use resume.
They have no load on the processor.
Because sleep(t) means "pause this thread for t mSec", i.e. it doesn't need anything external to kick it back into life. It's the sort of thing you'd use if e.g. enforcing a protocol delay in background communications.I thought the use of sleep or application.processmessage was considered negative from a programming perspective.
I thought the use of sleep or application.processmessage was considered negative from a programming perspective.
Is sleep used in professional programs?
But can I please point out that the only thing that is remotely relevant to OP's question is use of Application.ProcessMessages. All of this business about Sleep() etc. is spurious.Absolutely. At this stage I'd like to point out that the whole thing about Sleep() took a life of its own because SymbolicFrank suggested that Sleep() could be used as a better alternative to
I thought the use of sleep or application.processmessage was considered negative from a programming perspective.Application.ProcessMessages is usually negative now because today's OSs support multi-threading and implement preemptive multitasking. Application.ProcessMessages is something that was often necessary in the versions of Windows that required cooperative multitasking, their scheduler depended on the program voluntarily relinquishing the CPU to the scheduler and processing messages
Is sleep used in professional programs?
MarkMLl and Warfley and 440bx thank you very much for the enlightening information.
A little off topic:
I have a lot of questions in my mind, one of them is;
Does the running speed of threads change according to the language they are written in?
So is it possible that a thread written in a different language needs sleep, while a thread written in another language does not need sleep?
But all you've done there is replace Sleep() in a thread with Pause(), and wrapped it with event handling.This example shows all three conditions, i.e. timeout condition is one of them. But it's not necessary. The biggest difference here - you can interrupt pause manually, that is done in StopAndWaitFor not to wait for whole minute for thread to terminate. So block can actually be infinite. No reason to unblock from time to time to check thread termination condition.
Even if you were waiting for a library routine to complete something, there would still be something comparable with Sleep() involved. It might not be Sleep() as such since it might have separate code in the OS to detect the termination condition, but there would still be something which had the effect "suspend this thread but check occasionally to see if some condition is satisfied".
Interestingly, back in the earliest days of multitasking OSes, one ALGOL-60 implementation of which I'm aware had a procedure which allowed an (unprivileged) user's program to suspend itself until an absolute memory address was changed. I can't remember what this was supposed to be used for, but I'm sure that it really was a nightmare since a program could be moved to disc and then back to core while running at which point there was no guarantee that the absolute address being watched was still in its own storage area.
MarkMLl
My opinion: yeah, it can be harder to implement, but in such cases, when one needs async processes and API doesn't provide some built-in event mechanism - it's better to use threads. It's very bad idea to use any blocking API like Sleep in modern "passive" applications. It will most likely cause waste of CPU resources. Some cycles would be "lost" due to "sleeping" overhead and some cycles would be wasted due to constantly "waking up" to check external state. It's always better to use something like WaitForSingleObject or WaitForMultipleObjects inside thread. In this case there would be three methods to unblock thread: 1) You can unblock it by your own event - for example to terminate thread. 2) You can unblock it on timeout, if you need to do some tasks from time to time. 3) End you can unblock it by actual event, you need to wait for. This way thread will only consume CPU time, when it's really needed. And this way it could be woken at any moment without any overhead.
No, using threads only makes sense for long living processes. If you only need a timeout for a single operation (like the connect in my example), the creation of the thread structure in the operating system, the allocation of the stack memory and the management in the scheduler will add far more overhead to the system then having a polling mechanism.
It does have to be said though that unix doctrine seems to fork processes with gay abandon... and that would be expected to be substantially more complex that thread creation since it involves creating a new addressspace and either copying the existing process or setting up enough MMU state that it can be COWed on demand.Yes forking is really slow, around 1MS. Creating a fork is usually an order of magnitude faster at like 0.1 to 0.5 ms but this is still a massive overhead.
Noting of course that the OS/2 and Win32 APIs were heavily oriented towards asynchronous syscalls with callbacks (hence, reputedly, Horace Cutler's rant about byte-by-byte I/O in UNIX), I suppose that one possibility would be to emulate that by having a single background thread to which every blocking activity could be enqueued. That would obviously need to be used carefully, and there would obviously still be a sleep() or equivalent call somewhere.Yes the WinAPI also provides an asynchronous connect for sockets, but if you want to be cross compatible and stick to the Berkley Sockets API you won't get around either a watchdog thread or a polling sleep loop.
On Linux a thread is btw nothing more then a clone call with a certain configuration.
Especially fork gets slower the more often you call it from the same process. I once ran into the problem that a single fork took more than 1 minute. Solved it by using vfork instead.
When handling large parallel systems managing millions of connections it is even advised to not use threading and events managed by the system (and scheduled by the scheduler), because it is to slow. There it is best to have a few threads, each managing a few thousand connections, polling them at a high frequency and when having nothing to do do busy waiting. But then you also don't use sleep
Yeah I think what cannot be stressed enough is, don't use sleep in the main thread of a GUI application. GUI applications (or to be more general interactive applications) are event based. It is generally a sign of bad design if one tries to perform serialzed operations in an event based system.
It's always good thing to understand, that VCL - is just OOP wrapper around windows User32 library. So OnActivate - is wrapper around WM_ACTIVATE. In most cases it's important to know, whether message is sync or async, i.e. if it's sent or posted. If sender needs message result, then message should be sent. And in this case blocking it's handler means blocking sender execution. Overall there are 3 types of messages: 1) Posted, that is async and therefore sent via message queue 2) Sent, that is sync (i.e. window proc is called directly) for the same thread, but can be async for other thread 3) Message, that is always sync, because it's sent via calling window proc directly. It's true for something like WM_CREATE. At least in older Windows versions.
Yes sleep(0) will not reduce the CPU load, thats not the goal, it just yields to other processes so you don't starve them. If you want to actually reduce CPU usage you need to actually slow down your program (e.g. with sleep > 0)Why use sleep when you can suspend and use resume.
They have no load on the processor.
I thought the use of sleep or application.processmessage was considered negative from a programming perspective.Application.ProcessMessages is usually negative now because today's OSs support multi-threading and implement preemptive multitasking. Application.ProcessMessages is something that was often necessary in the versions of Windows that required cooperative multitasking, their scheduler depended on the program voluntarily relinquishing the CPU to the scheduler and processing messages
Is sleep used in professional programs?whichwas the gateway to those O/Ss schedulers regaining control.
Yes, and that also applies to the one-shot message that I was using to kick stuff off when I was using Delphi.Back in old times I had very good Visual Basic book, that wasn't about Visual Basic only - it was also about many Win32 tips and tricks.
I'd be surprised if anybody thought this merited serious investigation, and am not prepared to do it myself only to be told that the LCL was already working properly. But I suppose that the interesting thing is the way that the LCL (on Linux) /almost/ works in the way that Warfley and I hoped, with the exception of the focus issue.
MarkMLl
Suspend and Resume should not be used: you might suspend the thread while inside a critical section that is then never released until the thread is resumed and if the thread that controls the suspension and resuming then uses this critical section as well you'll have a deadlock. If you want to pause a thread until something from outside happens then wait on an event (which won't result in CPU load as well).
Application.ProcessMessages still has its place if you're doing some long running operation without using threads. E.g. updating a progress bar and listening for the click of a cancel button more often than not can be done without a thread (especially if the remainder of the UI is disabled).
Application.ProcessMessages still has its place if you're doing some long running operation without using threads. E.g. updating a progress bar and listening for the click of a cancel button more often than not can be done without a thread (especially if the remainder of the UI is disabled).IMO, if some activity takes long enough that it requires a progress bar then, that activity should be done by a thread other than the GUI thread and, that other thread can easily post a message to the GUI thread informing it of the need to update the progress bar and what its new value should be.