[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