无法执行线成同步方法:Synchronize中的线程方法HandleInput ( 积分: 50 )

  • 主题发起人 主题发起人 superdba
  • 开始时间 开始时间
S

superdba

Unregistered / Unconfirmed
GUEST, unregistred user!
开发环境:<br>windows 2000操作系统<br>delphi 2005<br><br>问题:<br>线程可以进入Execute过程执行<br>while not Terminated do begin<br> &nbsp;.... &nbsp;//省略号表示其它程序<br> &nbsp;Synchronize(HandleInput); &nbsp;[red]//该行打断点,程序执行到此,就无法执行下面showmessage语句了,另外HandleInput是我定义的一个线程过程,里面打了断点,也根本没执行到;但如果不使用 &nbsp;Synchronize(HandleInput); 语句,而是直接写成HandleInput;语句,则可以顺利执行进去,但由于没有使用Synchronize无法保证安全性.[/red] &nbsp;Showmessage('success call HandleInput');<br>end;
 
开发环境:<br>windows 2000操作系统<br>delphi 2005<br><br>问题:<br>线程可以进入Execute过程执行<br>while not Terminated do begin<br> &nbsp;.... &nbsp;//省略号表示其它程序<br> &nbsp;Synchronize(HandleInput); &nbsp;[red]//该行打断点,程序执行到此,就无法执行下面showmessage语句了,另外HandleInput是我定义的一个线程过程,里面打了断点,也根本没执行到;但如果不使用 &nbsp;Synchronize(HandleInput); 语句,而是直接写成HandleInput;语句,则可以顺利执行进去,但由于没有使用Synchronize无法保证安全性.[/red] &nbsp;Showmessage('success call HandleInput');<br>end;
 
线程里用不了showmessge,
 
to suninrain, 线程里可以用showmessge
 
可能是由于线程里执行Synchronize里函数后就不再执行后面的东东了。
 
to 代码哥哥,另外HandleInput是我定义的一个线程过程,里面第一行打了断点,也根本没执行到;
 
不会是主线程锁死了吧?<br>Synchronize执行的代码应该是在VCL的主线程内,类似于用SendMessage<br>而如果主线程处于死循环状态(类似),响应不了时,可能就无法执行你的代码了<br>我想Synchronize在可以不用时尽量不要用,它的流程不大容易理解
 
HandleInput 这个过程有问题,加上Synchronize时因为后边的showmessage要等HandleInput执行完才执行,如果HandleInput出错就会导致后边的语句不执行。<br>如果不加Synchronize,那么HandleInput和后边的showmessage可以认为是并行<br>执行的,也就是说执行后边的showmessage时HandleInput还没有执行完,所以<br>showmessage可以顺利执行。<br>你这样看看有什么结果:<br>try<br> &nbsp;Synchronize(HandleInput); &nbsp;[red]//该行打断点,程序执行到此,就无法执行下面<br>except on e:exception do<br> &nbsp;showmessage(e.message);<br>end;<br>Showmessage('success call HandleInput');
 
函数跟到以下这局无限时等待,出不来了,当然也无法去执行handleinput过程。如何解决?<br>class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);<br>var<br> &nbsp;SyncProc: TSyncProc;<br> &nbsp;SyncProcPtr: PSyncProc;<br>begin<br> &nbsp;if GetCurrentThreadID &lt;&gt; MainThreadID then<br> &nbsp; &nbsp;ASyncRec.FMethod<br> &nbsp;else<br> &nbsp;begin<br> &nbsp; &nbsp;if QueueEvent then<br> &nbsp; &nbsp; &nbsp;New(SyncProcPtr)<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;SyncProcPtr := @SyncProc;<br>{$IFDEF MSWINDOWS}<br> &nbsp; &nbsp;if not QueueEvent then<br> &nbsp; &nbsp; &nbsp;SyncProcPtr.Signal := CreateEvent(nil, True, False, nil)<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;SyncProcPtr.Signal := 0;<br> &nbsp; &nbsp;try<br>{$ENDIF}<br>{$IFDEF LINUX}<br> &nbsp; &nbsp; &nbsp;FillChar(SyncProcPtr^, SizeOf(SyncProcPtr^), 0); &nbsp;// This also initializes the cond_var<br>{$ENDIF}<br> &nbsp; &nbsp; &nbsp;EnterCriticalSection(ThreadLock);<br> &nbsp; &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp; &nbsp;SyncProcPtr.Queued := QueueEvent;<br> &nbsp; &nbsp; &nbsp; &nbsp;if SyncList = nil then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SyncList := TList.Create;<br> &nbsp; &nbsp; &nbsp; &nbsp;SyncProcPtr.SyncRec := ASyncRec;<br> &nbsp; &nbsp; &nbsp; &nbsp;SyncList.Add(SyncProcPtr);<br> &nbsp; &nbsp; &nbsp; &nbsp;SignalSyncEvent;<br> &nbsp; &nbsp; &nbsp; &nbsp;if Assigned(WakeMainThread) then<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WakeMainThread(SyncProcPtr.SyncRec.FThread);<br> &nbsp; &nbsp; &nbsp; &nbsp;if not QueueEvent then<br>{$IFDEF MSWINDOWS}<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LeaveCriticalSection(ThreadLock);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try<br>[red] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WaitForSingleObject(SyncProcPtr.Signal, INFINITE);[/red]<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;EnterCriticalSection(ThreadLock);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;end;
 
果然线程间死锁了,如果另一线程改动不了的话,那也就别用Synchronize过程了<br>换用其他办法
 
多人接受答案了。
 
后退
顶部