[Lazarus] custom thread reading file does not respond properly

Sven Barth pascaldragon at googlemail.com
Wed Sep 6 17:19:28 CEST 2017


Am 06.09.2017 16:48 schrieb "el es via Lazarus" <
lazarus at lists.lazarus-ide.org>:
>
> On 06/09/17 15:26, el es wrote:
> > On 06/09/17 10:31, Andrea Mauri via Lazarus wrote:
> >> Il 05/09/2017 22:51, Sven Barth via Lazarus ha scritto:
> >>>
> >>> It is however solved if you add a "Yield;" after the Synchronize
> >>> call. So my suspicion is that the scheduling of Mac OS X is somehow
> >>> messing things up. Either the scheduling is favoring the one thread
> >>> while it shouldn't (though even reducing the priority doesn't help)
> >>> or the UI framework of Mac OS X (and whatever else is involved in
> >>> the main thread) is so heavy weight that the timeslice of the
> >>> mainthread is used up more often than not thus leading to the read
> >>> thread being scheduled much more often. By using Yield (or also
> >>> Sleep(), but Yield is without any pause) the thread is explicitly
> >>> giving up its timeslice and that seems to be enough here...
> >>>
> >>
> >> I changed the code following your hints and I added Yield. This is
> >> not enough, it seems that the application is a little bit more
> >> responding (I can click on Tedit and after seconds the text is
> >> highlighted) but not enough to be usable. Actually for me it works
> >> only if I add at least Sleep(1). It is a pity that there is not a
> >> unique solution.
> >
> > Can you try ThreadSwitch after Sleep ?
> >
> > while (not Terminated) do
> >     begin
> >       if eof(f) then
> >         reset(f);
> >       ReadLn(f, newStatus);
> >       if NewStatus <> fStatusText then
> >       begin
> >         fStatusText := newStatus;
> >         //Queue(@ShowStatus);
> >         Synchronize(@Showstatus);
> >         Sleep(5);
> >         ThreadSwitch; /// <<<<
> >       end
> >       else  // also you need to cover what happens in ANY OTHER outcome
of any test, e.g.
> >         ThreadSwitch;
> >       // because if NewStatus = fStatusText, you will IMMEDIATELY jump
to the first instruction of the thread
> >       // so adding the ThreadSwitch at the very end of the loop, you
give the rest of the application (the main thread) a chance to
> >       // actually do anything
> >     end;
> >
> > Thread.Execute will execute ALL THE TIME if you don't
yield/threadswitch in some code path, and WILL saturate your CPU.
> >
> > -l,
> >
>
> In addition to why this isn't a problem on Windows or Linux: they have
supposedly better schedulers...
>
> but if not all codepaths on a thread are covered to give some time to
main thread, try to imagine what happens:
>
> - could the un-yielded code path lead to over-zealous enqueuing of the
ShowStatus routine?
> - if yes, what would happen in such case?

Both Synchronize and Sleep already causes a thread switch (the former cause
it will wait for the main thread to finish processing). Also I already
suggested TThread.Yield which is the same as ThreadSwitch.
And as he wrote the Sleep(1) solves the problem for him.
It's a pity though that this seems to be necessary on Mac OS X :/

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20170906/e68a2c72/attachment.html>


More information about the Lazarus mailing list