Delphi
猛禽[Studio Mental]
http://mental.mentsu.com
之五(大结局)
回到前面CheckSynchronize,见下面的代码:
fonction CheckSynchronize(Timeout : Integer = 0) : Booléen ;
var
SyncPRoc : PSyncProc ;
LocalSyncList : TList ;
commencer
si GetCurrentThreadID <> MainThreadID alors
augmenter EThread.CreateResFmt (@SCheckSynchronizeError, [GetCurrentThreadID]);
si Timeout > 0 alors
WaitForSyncEvent (délai d'expiration)
autre
RéinitialiserSyncEvent ;
LocalSyncList := néant ;
EnterCriticalSection(ThreadLock);
essayer
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
essayer
Résultat := (LocalSyncList <> nil) et (LocalSyncList.Count > 0) ;
si Résultat alors
commencer
tandis que LocalSyncList.Count > 0 fait
commencer
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
essayer
essayer
SyncProc.SyncRec.FMethod ;
sauf
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
fin;
enfin
EnterCriticalSection(ThreadLock);
fin;
SetEvent(SyncProc.signal);
fin;
fin;
enfin
LocalSyncList.Free ;
fin;
enfin
LeaveCriticalSection(ThreadLock);
fin;
fin;
首先,这个方法必须在主线程中被调用(如前面通过消息传递到主线程),否则就抛出异常。
Il s'agit de ResetSyncEvent (et de SetSyncEvent) et de WaitForSyncEvent. Pour Linux, il y a CheckSynchronize et Windows pour CheckSynchronize.
Liste de synchronisation des listes de synchronisation :所有未被执行的同步方法的。因为主线程只有一个,而子线程可能有很多个,当多个子线程同时调用同步方法时,主线程可能一时无法处理,所以需要一个列表来记录它们。
在这里用一个局部变量LocalSyncList来交换SyncList,这里用的也是一个原语:I nterlockedExchange.
Il existe une liste de synchronisation locale et une liste de synchronisation locale. Il s'agit d'une liste de synchronisation locale.
再来看对同步方法的处理:首先是从列表中移出(取出并从列表中删除)第原因当然也是为了防止死锁)。
接着就是真正的调用同步方法了。
如果同步方法中出现异常,将被捕获后存入同步方法数据记录中。
Il s'agit d'une application SetEvent, et d'une application SetEvent. Comment Synchroniser avec WaitForSingleObject调用)
至此,整个Synchronize的实现介绍完成。
最后来说一下WaitFor,它的功能就是等待线程执行结束。其代码如下:
fonction TThread.WaitFor : LongWord ;
var
H : tableau[0..1] de THandle ;
WaitResult : Cardinal ;
Message : message TM ;
commencer
H[0] := FPoignée ;
si GetCurrentThreadID = MainThreadID alors
commencer
Résultat d'attente := 0 ;
H[1] := SyncEvent;
répéter
{ Cela évite un blocage potentiel si le thread d'arrière-plan
fait un SendMessage au fil de discussion de premier plan }
si WaitResult = WAIT_OBJECT_0 + 2 alors
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
CheckThreadError(WaitResult <> WAIT_FAILED);
si WaitResult = WAIT_OBJECT_0 + 1 alors
VérifierSynchroniser ;
jusqu'à WaitResult = WAIT_OBJECT_0 ;
fin sinon WaitForSingleObject(H[0], INFINITE);
CheckThreadError(GetExitCodeThread(H[0], Résultat));
fin;
Il s'agit de WaitFor, et de WaitForSingleObject, Handle avec Signaled.
如果是在主线程中执行WaitFor则比较麻烦。首先要在Hand le数组中增加一个SyncEvent,然后循环等待,直到线程结Il s'agit de MsgWaitForMultipleObjects et de WAIT_OBJECT_0, ainsi que de MSDN avec API.
在循环等待中作如下处理:如果有消息发生,则通过PeekMes sage取出此消息(但并不把它从消息循环中移除),然后调用M sgWaitForMultipleObjects utilise Handle pour SyncEvent et Signaled, ainsi que Il s'agit de l'API QS_SENDMESSAGE et de l'API MSDN. dleWaitForSingleObject et SyncEventSetEvent(返回WAIT_OBJECT_0 + 1),et CheckSynchronize处理同步方法。
Comment utiliser WaitFor pour MsgWaitForMultipleObjects "WaitForSingleObject" La fonction Synchroniser est également compatible avec WaitForSin. gleObject等待的话,则主线程在这里被挂起,同步方法无法执行,导致线程也被挂起,于是发生死锁。
Il y a une erreur dans WaitForMultipleObjects. La gestion de Handle et SyncEvent est terminée par Signaled et QS_SEND. Message MESSAGE Synchroniser Synchroniser调用,在调用完成后继续进入挂起等待状态,直到线程结束。
至此,对线程类TThread的分析可以告一个段落了,对前面的分析作一个总结:
1、线程类的线程必须按正常的方式结束,et Execute执行结束,所以在其中的代码中必须在适当的地方加入足够多的对T terminé标志的判断,并及时退出。如果必须要"立即"退出,则不能使用线程类,而要改用API或RTL函数。
2. La fonction VCL Synchronize est une fonction de synchronisation.
3. La synchronisation est effectuée.
4. La fonction de suspension/reprise de l'événement.
5、 当在多线程应用中使用多种线程同步方式时,一定要小心防止出现死锁。
6、 等待线程结束要用WaitFor方法。
01-03 décembre
(终于续完了)