[fpc-pascal] Where is IsMultiThreaded set under Linux?
Sven Barth
pascaldragon at googlemail.com
Fri Oct 8 16:27:51 CEST 2010
Am 08.10.2010 14:03, schrieb Graeme Geldenhuys:
>
> if IsMultiThreaded then
> begin
> writeln('******');
> CheckSynchronized();
> end;
>
>
[snip]
>
> procedure TBarThread.Execute;
> begin
> FFinished := False; // work-around variable
> while not Terminated do
> begin
> Synchronize(@UpdateProgressBar);
> end;
> FFinished := True; // work-around variable
> end;
>
[snip]
>
> procedure TMainForm.ButtonClicked(Sender: TObject);
> begin
> ProgressBar1.Position := ProgressBar1.Min;
> if not Assigned(FThread) then
> begin
> writeln('program: creating thread...');
> FThread := TBarThread.Create(True);
> FThread.ProgressBar := ProgressBar1;
> end;
> writeln('program: starting the thread...');
> FThread.Start;
>
> writeln('program: waiting for thread...');
> FThread.WaitFor; // Can use this, it blocks the main event loop
>
> // my work-around
> while not FThread.Finished do
> begin
> sleep(100);
> fpgApplication.ProcessMessages;
> end;
>
> writeln('program: thread is finished!');
> Label1.Text := 'Thread is done';
> FreeAndNil(FThread);
> end;
Looking again at your example code explains very clearly what happens (I
assume the CheckSynchronize call is in your ProcessMessages method):
In the thread you call Synchronize which will stop the thread until the
main thread has found time to process all queued Synchronize messages
(by calling CheckSynchronize). Read again: the thread is SUSPENDED, it's
in a waiting state.
Now you call .WaitFor during an event handler. So you wait until the
thread is finished.
There is the problem: The main thread is waiting for the second thread
to finish and the second thread is waiting for the main thread to find
time to process its synchronized message. This is a classical DEADLOCK.
The "workaround" is not really a workaround, but more a "clean solution"
(there are other ones that others already mentioned like running an
OnTerminate-event, which is supported on Delphi as well).
And it doesn't appear on Windows, because WaitFor uses
MsgWaitForMultipleObjects which waits for either the thread's handle,
the synchronize timeout (in which case CheckSynchronize is run) or a
message that is send from Windows' message system (which is then
processed). So a Windows GUI won't hang (Sergei has mentioned this on
the Lazarus list).
So from the following statement:
> So what is wrong? Is it the TThread.WaitFor implementation that is
> flawed? Is it X11 that is flawed, or just GUI toolkit developers that
> don't know how to code (thought I doubt it's the latter).
I'll choose the third option. ;P (please don't be offended)
Regards,
Sven
More information about the fpc-pascal
mailing list