Delphi의 최신 버전
猛禽[멘탈 스튜디오]
http://mental.mentu.com
之五(大结局)
回到앞면CheckSynchronize,见下면的代码:
함수 CheckSynchronize(Timeout: Integer = 0): 부울;
var
SyncPROc: PSyncProc;
LocalSyncList: TList;
시작하다
GetCurrentThreadID <> MainThreadID인 경우
EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID])를 올리십시오.
시간 초과 > 0이면
WaitForSyncEvent(시간 초과)
또 다른
ResetSync이벤트;
LocalSyncList := nil;
EnterCriticalSection(ThreadLock);
노력하다
Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
노력하다
결과 := (LocalSyncList <> nil) 및 (LocalSyncList.Count > 0);
결과가 그렇다면
시작하다
LocalSyncList.Count > 0인 동안
시작하다
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
LeaveCriticalSection(ThreadLock);
노력하다
노력하다
SyncProc.SyncRec.FMethod;
제외하고
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
끝;
마지막으로
EnterCriticalSection(ThreadLock);
끝;
SetEvent(SyncProc.signal);
끝;
끝;
마지막으로
LocalSyncList.Free;
끝;
마지막으로
LeaveCriticalSection(ThreadLock);
끝;
끝;
首先,这个방법必须이 主线程中被调用(如前面过消息传递到主线程),否则就抛异常。
接下来调用ResetSyncEvent(它与前面SetSyncEvent对应的, 之所以不考虑WaitForSyncEvent的情况,是因为只현재 Linux에서는 CheckSynchronize를 사용하고 있으며 Windows에서는 CheckSynchronize를 사용하고 있습니다.
现에서 SyncList를 사용하는 데는 다음과 같은 것들이 있습니다.线程可能有很多个, 当多个子线程同时调用同步方法时,主线程可能一时无法处理,所以需要一个列表来记录它们。
여기에서 LocalSyncList를 사용하여 SyncList를 사용하고 있으며 InterlockedExchange를 사용하고 있습니다.
LocalSyncList는 일반적으로 사용되지 않으며 일반적으로 사용되는 LocalSyncList와 동일합니다.
再来看对同步方法的处理:首先是从列表中移出(取并从列表中删除)第一个同步방법调사용数据。
接着就是真真는 올바른 사용 방법과 동일합니다.
如果同步方法中출진异常,将被捕获后存入同步方法数据记录中.
새로운 기능은 SetEvent를 통합적으로 알려줍니다.
至此,整个Synchronize 实现介绍完成。
最后来说一下 WaitFor,它的功能就是等待线程执行结束。其代码如下:
함수 TThread.WaitFor: LongWord;
var
H: THandle의 배열[0..1];
대기 결과: 추기경;
메시지: TMsg;
시작하다
H[0] := FHandle;
GetCurrentThreadID = MainThreadID인 경우
시작하다
대기결과 := 0;
H[1] := SyncEvent;
반복하다
{ 이렇게 하면 백그라운드 스레드가
SendMessage를 포그라운드 스레드로 보냅니다. }
WaitResult = WAIT_OBJECT_0 + 2이면
PeekMessage(메시지, 0, 0, 0, PM_NOREMOVE);
WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
CheckThreadError(WaitResult <> WAIT_FAILED);
WaitResult = WAIT_OBJECT_0 + 1이면
동기화를 확인하세요.
WaitResult = WAIT_OBJECT_0까지;
end else WaitForSingleObject(H[0], INFINITE);
CheckThreadError(GetExitCodeThread(H[0], Result));
끝;
WaitForSingleObject는 신호를 받은 핸들을 사용하여 WaitForSingleObject를 사용할 수 없습니다.
如果是는 主线程中执行WaitFor则比较麻烦를 기다리십시오.束(即MsgWaitForMultipleObjects返回WAIT_OBJECT_0,详见MSDN中关于此API的说明).
에서 循环等待中作如下处理:如果有消息发生,则通过PeekMessage取流此消息(但并不把它从消息循环中移除),然后调除) sgWaitForMultipleObjects가 Handle或SyncEvent를 생성하여 Signaled를 보냅니다.听消息(QS_SENDMESSAGE参数,详见MSDN中关于此API的说明)。可以把此API当work一个可以同时等待多个Han WaitForSingleObject. SyncEvent被SetEvent(返回WAIT_OBJECT_0 + 1), CheckSynchronize를 사용하여 관리하는 방법입니다.
为什么에서 主线程中调用 WaitFor必须用 MsgWaitForMultipleObjects,而不能用WaitForSingleObject等待线程结束呢?因为防止死锁。由于在线程函数Execute中可能调는 동기화를 동기화하는 방법과 동일한 방법을 사용하여 WaitForSin을 사용합니다. gleObject는 则主线程에서 这里被挂起, 同步方法无法执行,导致线程也被挂起,于是发生死锁。
而改用WaitForMultipleObjects则没有这个问题。首先,它的第三个参数为False,表示只要线程Handle或SyncEvent中只要有一个Signaled即可使主线程被唤醒,至于加QS_SEND 메시지는 동기화를 통해 동기화됩니다. 동기화 기능을 사용하면 동기화 기능을 사용할 수 있습니다.
至此,对线程类TThread 分析可以告一个段落了,对前线程类TThread 分析可以告一个段落了,对前线程类Tthread 分析作一个总结:
1、线程类的线程必须按正常 的 方式结束,即Execute执行结束 , 所以在其中 的 代码中必须 에서 适当 的地方加入足够多对T 제거된 判断, 并及时退出.
2, 对可视VCL的访问要放는Synchronize中, 일반적으로 过消息传递到主线程中,由主线程处り입니다.
3. 线程共享数据的访问应该用临界区进行保护(当然用Synchronize也行).
4、 线程通信可以采사용이벤트进行(当然也可以用Suspend/Resume)。
5. 当에서 多线程应用中使를 多种线程同步方式时,一当要小心防止流现死锁。
6、 等待线程结束要用 Wait For Method。
12월 1일~03일
(终于续完了)