亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

Delphi中的線程類--之(5,大結局)

2019-11-18 18:27:57
字體:
來源:轉載
供稿:網友
 

Delphi中的線程類

 

猛禽[Mental Studio]

http://mental.mentsu.com

 

之五(大結局)

回到前面CheckSynchronize,見下面的代碼:

function CheckSynchronize(Timeout: Integer = 0): Boolean;

var

  SyncPRoc: PSyncProc;

  LocalSyncList: TList;

begin

  if GetCurrentThreadID <> MainThreadID then

    raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);

  if Timeout > 0 then

    WaitForSyncEvent(Timeout)

  else

    ResetSyncEvent;

  LocalSyncList := nil;

  EnterCriticalSection(ThreadLock);

  try

    Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));

    try

      Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);

      if Result then

      begin

        while LocalSyncList.Count > 0 do

        begin

          SyncProc := LocalSyncList[0];

          LocalSyncList.Delete(0);

          LeaveCriticalSection(ThreadLock);

          try

            try

              SyncProc.SyncRec.FMethod;

            except

              SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;

            end;

          finally

            EnterCriticalSection(ThreadLock);

          end;

          SetEvent(SyncProc.signal);

        end;

      end;

    finally

      LocalSyncList.Free;

    end;

  finally

    LeaveCriticalSection(ThreadLock);

  end;

end;

首先,這個方法必須在主線程中被調用(如前面通過消息傳遞到主線程),否則就拋出異常。

接下來調用ResetSyncEvent(它與前面SetSyncEvent對應的,之所以不考慮WaitForSyncEvent的情況,是因為只有在linux版下才會調用帶參數的CheckSynchronize,Windows版下都是調用默認參數0CheckSynchronize)。

現在可以看出SyncList的用途了:它是用于記錄所有未被執行的同步方法的。因為主線程只有一個,而子線程可能有很多個,當多個子線程同時調用同步方法時,主線程可能一時無法處理,所以需要一個列表來記錄它們。

在這里用一個局部變量LocalSyncList來交換SyncList,這里用的也是一個原語:InterlockedExchange。同樣,這里也是用臨界區將對SyncList的訪問保護起來。

只要LocalSyncList不為空,則通過一個循環來依次處理累積的所有同步方法調用。最后把處理完的LocalSyncList釋放掉,退出臨界區。

再來看對同步方法的處理:首先是從列表中移出(取出并從列表中刪除)第一個同步方法調用數據。然后退出臨界區(原因當然也是為了防止死鎖)。

接著就是真正的調用同步方法了。

如果同步方法中出現異常,將被捕獲后存入同步方法數據記錄中。

重新進入臨界區后,調用SetEvent通知調用線程,同步方法執行完成了(詳見前面Synchronize中的WaitForSingleObject調用)。

至此,整個Synchronize的實現介紹完成。

 

最后來說一下WaitFor,它的功能就是等待線程執行結束。其代碼如下:

function TThread.WaitFor: LongWord;

var

  H: array[0..1] of THandle;

  WaitResult: Cardinal;

  Msg: TMsg;

begin

  H[0] := FHandle;

  if GetCurrentThreadID = MainThreadID then

  begin

    WaitResult := 0;

    H[1] := SyncEvent;

    repeat

      { This prevents a potential deadlock if the background thread

        does a SendMessage to the foreground thread }

      if WaitResult = WAIT_OBJECT_0 + 2 then

        PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);

      WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);

      CheckThreadError(WaitResult <> WAIT_FAILED);

      if WaitResult = WAIT_OBJECT_0 + 1 then

        CheckSynchronize;

    until WaitResult = WAIT_OBJECT_0;

  end else WaitForSingleObject(H[0], INFINITE);

  CheckThreadError(GetExitCodeThread(H[0], Result));

end;

如果不是在主線程中執行WaitFor的話,很簡單,只要調用WaitForSingleObject等待此線程的HandleSignaled狀態即可。

如果是在主線程中執行WaitFor則比較麻煩。首先要在Handle數組中增加一個SyncEvent,然后循環等待,直到線程結束(即MsgWaitForMultipleObjects返回WAIT_OBJECT_0,詳見MSDN中關于此API的說明)。

在循環等待中作如下處理:如果有消息發生,則通過PeekMessage取出此消息(但并不把它從消息循環中移除),然后調用MsgWaitForMultipleObjects來等待線程HandleSyncEvent出現Signaled狀態,同時監聽消息(QS_SENDMESSAGE參數,詳見MSDN中關于此API的說明)??梢园汛?/SPAN>API當作一個可以同時等待多個HandleWaitForSingleObject。如果是SyncEventSetEvent(返回WAIT_OBJECT_0 + 1),則調用CheckSynchronize處理同步方法。

為什么在主線程中調用WaitFor必須用MsgWaitForMultipleObjects,而不能用WaitForSingleObject等待線程結束呢?因為防止死鎖。由于在線程函數Execute中可能調用Synchronize處理同步方法,而同步方法是在主線程中執行的,如果用WaitForSingleObject等待的話,則主線程在這里被掛起,同步方法無法執行,導致線程也被掛起,于是發生死鎖。

而改用WaitForMultipleObjects則沒有這個問題。首先,它的第三個參數為False,表示只要線程HandleSyncEvent中只要有一個Signaled即可使主線程被喚醒,至于加上QS_SENDMESSAGE是因為Synchronize是通過消息傳到主線程來的,所以還要防止消息被阻塞。這樣,當線程中調用Synchronize時,主線程就會被喚醒并處理同步調用,在調用完成后繼續進入掛起等待狀態,直到線程結束。

 

至此,對線程類TThread的分析可以告一個段落了,對前面的分析作一個總結:

1、  線程類的線程必須按正常的方式結束,即Execute執行結束,所以在其中的代碼中必須在適當的地方加入足夠多的對Terminated標志的判斷,并及時退出。如果必須要“立即”退出,則不能使用線程類,而要改用APIRTL函數。

2、  對可視VCL的訪問要放在Synchronize中,通過消息傳遞到主線程中,由主線程處理。

3、  線程共享數據的訪問應該用臨界區進行保護(當然用Synchronize也行)。

4、  線程通信可以采用Event進行(當然也可以用Suspend/Resume)。

5、  當在多線程應用中使用多種線程同步方式時,一定要小心防止出現死鎖。

6、  等待線程結束要用WaitFor方法。

 

Dec.01-03

(終于續完了)


上一篇:用DELPHI實現NT環境下的絕對磁盤讀寫

下一篇:Delphi中的線程類--之(4)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久色免费在线视频| 亚洲欧美另类国产| 色综合视频网站| 国产精品都在这里| 亚洲欧美在线免费观看| 欧美日韩国产中文字幕| 久久青草精品视频免费观看| 国产精品久久久久久久久久久久| 亚洲天天在线日亚洲洲精| 欧美性少妇18aaaa视频| 91在线观看免费观看| 91免费看片在线| 欧美大成色www永久网站婷| 韩日精品中文字幕| 国产一区二区免费| 亚洲日本成人网| 欧美成人精品在线| 777精品视频| 欧美精品福利视频| 日本高清久久天堂| 国语自产在线不卡| 亚洲电影在线看| 不卡av电影在线观看| 91色视频在线导航| 91免费精品国偷自产在线| 欧美一区二区三区艳史| 欧美精品videos性欧美| 日韩精品小视频| 免费91在线视频| 奇米一区二区三区四区久久| 欧美性少妇18aaaa视频| 2021久久精品国产99国产精品| 国产亚洲一区二区精品| 国产精品狠色婷| 中文字幕精品网| 亚洲精品国产精品乱码不99按摩| 国产亚洲欧美另类中文| 国产99久久久欧美黑人| 日韩免费观看视频| 欧美日韩国产二区| 国产精品aaaa| 欧美一级淫片aaaaaaa视频| 欧美激情免费观看| 成人黄色片在线| 精品视频在线播放色网色视频| 国产精品日韩在线一区| 日韩高清电影免费观看完整| 欧美日韩裸体免费视频| 国产精品精品国产| 国产伊人精品在线| 日韩av在线免费播放| 色婷婷**av毛片一区| 国产精品久久一| 欧美俄罗斯性视频| 国产精品扒开腿爽爽爽视频| 在线国产精品播放| 国产欧美日韩中文字幕| 97在线视频观看| 亚洲精品www久久久久久广东| 国产精品高潮呻吟久久av无限| 亚洲天堂2020| 国产日韩在线亚洲字幕中文| 精品爽片免费看久久| 最近2019年中文视频免费在线观看| 精品视频久久久久久| 亚洲欧美精品中文字幕在线| 日韩在线视频二区| 亚洲欧美日韩图片| 久久97久久97精品免视看| 欧美极品少妇xxxxⅹ裸体艺术| 欧美男插女视频| 国产精品成久久久久三级| 91av中文字幕| 中文字幕日韩在线视频| 一夜七次郎国产精品亚洲| 亚洲va国产va天堂va久久| 亚洲高清一二三区| 日韩中文理论片| 成人黄色午夜影院| 丝袜美腿精品国产二区| 欧美成人久久久| 日韩精品在线视频观看| 久久久久久久久久国产精品| 亚洲free嫩bbb| 国产欧美va欧美va香蕉在线| 啪一啪鲁一鲁2019在线视频| 欧美洲成人男女午夜视频| 色综合久综合久久综合久鬼88| 欧美极品少妇xxxxⅹ喷水| 欧美疯狂性受xxxxx另类| 欧美中文字幕在线视频| 亚洲人成人99网站| 久久综合免费视频| 国产成人自拍视频在线观看| 欧美激情啊啊啊| 亚洲图片在线综合| 国产亚洲美女精品久久久| 久久精品久久久久电影| 91精品国产自产在线老师啪| 国产欧美精品在线播放| 日韩中文在线中文网三级| 亚洲精品中文字幕av| 国产在线精品一区免费香蕉| 亚洲午夜av久久乱码| 国产精品黄色影片导航在线观看| 日韩欧美中文第一页| 欧美日韩国产成人| 国产精品三级在线| 自拍偷拍亚洲区| 国产不卡一区二区在线播放| 97精品国产91久久久久久| 97久久精品人人澡人人爽缅北| 国产一区二区三区视频在线观看| 精品一区二区三区电影| 日韩福利在线播放| 国产精品18久久久久久首页狼| 久久成人人人人精品欧| 91在线|亚洲| 欧美精品在线视频观看| 欧美激情欧美狂野欧美精品| 日韩精品在线免费播放| 亚洲人高潮女人毛茸茸| 中文字幕日韩精品在线观看| 久久人人爽人人爽人人片亚洲| 国产精品久久久久久久电影| 欧美人与性动交a欧美精品| 久久久久久一区二区三区| 欧洲美女免费图片一区| 国产欧美精品一区二区三区-老狼| 国产在线精品播放| 一本色道久久综合狠狠躁篇的优点| 日韩综合中文字幕| 日韩精品极品毛片系列视频| 国产精品高清免费在线观看| 国产精品27p| 最近中文字幕2019免费| 成人h猎奇视频网站| 川上优av一区二区线观看| 亚洲天堂开心观看| 91高清视频在线免费观看| 久久人人爽人人爽人人片av高请| 成人性生交大片免费观看嘿嘿视频| 一本大道久久加勒比香蕉| 久久夜精品va视频免费观看| 色综合男人天堂| 欧美中文在线视频| 国产网站欧美日韩免费精品在线观看| 欧美日韩性视频| 欧美电影在线观看| 国产在线精品一区免费香蕉| 91精品视频免费| 欧美夫妻性视频| 国内精品久久久久久中文字幕| 91在线视频导航| 欧美在线一级va免费观看| 91精品视频免费看| 国产精品久久久久久久久影视| 中文字幕亚洲无线码a| 亚洲人成亚洲人成在线观看| 2019亚洲日韩新视频| 国产成人拍精品视频午夜网站| 2019av中文字幕| 国产欧美精品在线播放| 亚洲国产精品yw在线观看|