Board index » delphi » Dead Lock in Threads Synchronizing

Dead Lock in Threads Synchronizing

Hi all,

I found a strange question in threads synchronizing which causes deadlock.
My code is as following:

procedure TForm1.BitBtnRunClick(Sender: TObject);
var  i, num: integer;
begin
     hSemWait := CreateSemaphore(nil,0,1,nil);
     hSemResource := CreateSemaphore(nil,0,num,nil);
     for i := 1 to ThreadsRunning do
         with TMyThread.Create(hSemResource) do
              OnTerminate := ThreadDone;
     ReleaseSemaphore(hSemResource,num,nil);
     WaitForSingleObject(hSemWait,INFINITE);
     showmessage('finished');
end;

procedure TForm1.ThreadDone(Sender: TObject);
begin
     Dec(ThreadsRunning);
     if ThreadsRunning=0 then
          ReleaseSemaphore(hSemWait,1,nil);
end;

procedure TMyThread.Execute;
begin
     //FSem := hSemWait in Create
     WaitForSingleObject(FSem,INFINITE);
     DoSomeThing;
     ReleaseSemaphore(FSem,1,nil);
end;

I use hSemWait to synchronize main thread and child threads, hSemResource
to solve child threads conflicting.
It seems right but it will certain cause deadlock. If I remove the WaitFor...
in main thread, it works.

So I guess that is caused due to that in a message handler main thread cannot
wait. That is to say a message is not completed handling and must wait for
another message, so the result is deadlock.

Who can give me some suggestion to solve the deadlock problem and synchrohize
the main thread and child thread?
Any helps appreciated!

Ouyang

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

 

Re:Dead Lock in Threads Synchronizing


Quote
In article <6ct6hv$96...@nnrp2.dejanews.com> mouy...@yahoo.com writes:
>I found a strange question in threads synchronizing which causes deadlock.
>My code is as following:
>procedure TForm1.BitBtnRunClick(Sender: TObject);
>var  i, num: integer;
>begin
>     hSemWait := CreateSemaphore(nil,0,1,nil);
>     hSemResource := CreateSemaphore(nil,0,num,nil);
>     for i := 1 to ThreadsRunning do
>         with TMyThread.Create(hSemResource) do
>              OnTerminate := ThreadDone;
>     ReleaseSemaphore(hSemResource,num,nil);
>     WaitForSingleObject(hSemWait,INFINITE);
>     showmessage('finished');
>end;
>procedure TForm1.ThreadDone(Sender: TObject);
>begin
>     Dec(ThreadsRunning);
>     if ThreadsRunning=0 then
>          ReleaseSemaphore(hSemWait,1,nil);
>end;
>procedure TMyThread.Execute;
>begin
>     //FSem := hSemWait in Create
>     WaitForSingleObject(FSem,INFINITE);
>     DoSomeThing;
>     ReleaseSemaphore(FSem,1,nil);
>end;
>I use hSemWait to synchronize main thread and child threads, hSemResource
>to solve child threads conflicting.
>It seems right but it will certain cause deadlock. If I remove the WaitFor...
>in main thread, it works.
>So I guess that is caused due to that in a message handler main thread cannot
>wait. That is to say a message is not completed handling and must wait for
>another message, so the result is deadlock.
>Who can give me some suggestion to solve the deadlock problem and synchrohize
>the main thread and child thread?
>Any helps appreciated!

The following excerpt from the TThread.WaitFor description in Delphi help
might be useful:
[snip!]
Don't call WaitFor in the context of the main VCL thread if your thread uses
Synchronize. Doing so will either cause a deadlock, making it appear that your
application has hung, or cause an EThread exception to be raised. (Synchronize
waits for the main VCL thread to enter the message loop before allowing the
method it is trying to synchronize to execute.
==> If the main VCL thread has called WaitFor, it won't enter the message loop
and Synchronize will never return. <==
 TThread detects that case and will raise an EThread exception in the
thread, causing it to terminate and, if not caught in the Execute method, the
application will terminate as well. If Synchronize is already waiting on the
main VCL thread when WaitFor is called, TThread can't intervene, and your
application will deadlock.)
[snip!]

Apparently it is not a good idea for the main-thread to enter a condition
where it cannot process the message queue.

What you should probably do is to use a user-defined message that is posted to
the main-thread's message queue when each thread ends.  The main thread
decrements a counter each time such a message is received, and does not
terminate until the counter becomes zero.

Other Threads