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