熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

DELPHI下的多線程程序設計

2013-11-23 17:46:47  來源: Delphi編程 
我們知道win或winNT都是多線程的操作系統在DELPHI 我們可以充分利用這一特性編寫出多線程的應用程序

  對以往在DOS或位windows下寫程序的人來說多線程仍然是陌生的但如同以前我們從DOS下的單任務過渡到windows下的多任務如今我們又必須過渡到多線程領域畢竟計算機時代是在不斷發展的不過幸運的是在DELPHI下進行多線程程序設計並不需要我們去學習龐大的WINAPI函數我們可以利用DELPHI下標准的多線程類TThread來完成我們的工作
 
  TThread是一個abstract(抽象)類也就是說並不需要根據TThread來聲明變量(而且根據TThread聲明的變量也是完全無用)我們要做的是把TThread作為基類用繼承的形式來生成子類實際上根據TThread來寫多線程應用程序是非常容易的

  下面就是一個基本的繼承TThread生成的多線程類

  QuerThrd.Pas
  unitQuerThrd
  interface
  uses
  ClassesDBTables
  type
  TQueryThreadΚclass(TThread)
  private
  fQuerytQuery
  protected
  procedureExecuteoverride
  public
  constructorCreate(SuspendedBooleanQueryTQuery)
  end
  implementation
  constructor
  TQueryThread.Create(SuspendedBooleanQueryTQuery)
  begin
  inheritedCreate(Suspended)
  fQueryΚQuery
  FreeOnTerminateΚTrue
  end
  procedureTQueryThread.Execute
  begin
  fQuery.Open
  end
  end.

  在上面這個簡單的例子中我們構造了一個TThread的子類TQueryThread用於在後台執行數據庫查詢在該類的Create函數中傳遞了兩個參數Suspended和Query其中Suspended用於控制線程的運行如果Suspend為真TQueryThread類的線程在建立後將立即被懸掛一直到運行了Resume方法該線程才會繼續執行Query參數用於接受一個已經存在的Query控件(在窗體中真正的Query控件)而使它在多線程的情況下運行Execute是最重要的過程它是類TQueryThread的執行部分所有需要在這個多線程類中運行的語句都必須寫在這個過程裡

  實際上構造自己的多線程類時並不需要輸入所有的這些代碼選擇DELPHI的File菜單下的new選項再選TThreadObject項目DELPHI就會為你構造基本的程序模塊然後我們可以根據需要再做相應的修改

  進程的執行

  假設我們已經建立了一個窗體FORM窗體中有我們將要使用的查詢控件Query那麼我們在該單元的USES部分加入上面寫的QuerThrd單元

  procedureTForm.ButtonClick(SenderTObject)
  begin
  {建立一個運行的進程}
  TQueryThread.Create(FalseQuery
  end

  如果這個過程被執行那麼窗體中的查詢控件Query就會自動在多線程的環境下運行查詢注意TQueryThread類中只有Create而沒有Free動態建立類以後又忘記刪除是我們常犯的錯誤之一不過在這裡由於我們指定了FreeOnTerminate(運行完即刪除)為真所以當Execute裡的語句執行完後TQueryThread類占據的內存控件將被自動釋放

  然而還有一個問題值得我們注意由於同一時刻可以有多個線程同時運行那麼我們還必須解決好同步的問題如果幾個多線程程序之間沒有任何關聯那麼它們之間也不會有任何沖突但實際上可能同時運行幾個多線程的數據庫應用程序由於需要共享相同的數據庫資源我們還需要為Query增加一個Tsession控件

  其實雖然我們也許沒有親自使用過Session控件但實際上在所有的數據庫訪問時DELPHI都會自動建立一個臨時的Session控件使用完後又動態地刪除掉它在平常的數據庫編程時用不著我們親自來操作但在數據庫多線程執行的情況下為了不相互沖突我們必須為每個數據庫訪問都定制自己的Session控件這個步驟非常簡單我們只需要在窗體中增加一個Session控件然後給它的屬性Sessionname寫一個任意的名字並再在QuerySessionname中寫一個相同的名字這樣我們的數據庫程序就安全了

  另一類需要解決同步問題的是那些對VCL資源進行操作的程序這類的程序非常多好在解決的方法也非常簡單

  我們可以看下面這樣一個程序

  unitBncThrd
  interface
  uses
  WinProcsClassesGraphicsExtCtrls
  type
  TBounceThreadΚclass(TThread)
  private
  FShapeTShape
  FXSpeedInteger
  FYSpeedInteger
  procedureMoveShape
  protected
  procedureExecuteoverride
  public
  constructorCreate(SuspendedBooleanShapeTShapeXSpeedYSpeedInteger)
  propertyShapeTShapereadFShape
  end
  implementation
  procedureTBouad.MoveShape
  var
  MaxHeightMaxWidthInteger
  begin
  withFShapedo
  begin
  LeftΚLeft+FXSpeed
  TopΚTop+FYSpeed
  if(LeftΙ)or
  (Left+WidthΛParent.Width)then
  FXSpeedΚFXSpeed*-
  if(TopΙ)or
  (Top+HeightΛParent.Height)then
  FYSpeedΚFYSpeed*-
end
  end
  procedureTBounceThread.Execute
  begin
  WhilenotTerminateddo
  begin
  Synchronize(MoveShape)
  end
  end
  constructorTBounceThread.Create(SuspendedBooleanShapeTShapeXSpeedYSpeedInteger)
  begin
  inheritedCreate(Suspended)
  FShapeΚShape
  FXSpeedΚXSpeed{X軸走向的速度}
  FYSpeedΚYSpeed{Y軸走向的速度}
  FreeOnTerminateΚTrue
  end
  end.

  這是一個多線程的碰碰球游戲你可以有多個不同的球它們分屬不同的線程各自獨立的在屏幕上碰撞顯然由於多個球運行的顯示會同時操作VCL資源為了安全我們在Execute過程中的執行部分加入了Synchronize(MoveShape)來調用MoveShape過程實際上在任何需要操作VCL資源的地方例如窗體位圖都應加入Synchronize調用

  執行時我們可以新建一個程序然後在USES部分加入以上的BncThrd單元再在它的窗體FORM上加入兩個Shape控件Shape和ShapeShape可以是一個矩形而Shape是一個圓加入以下的代碼就可以讓矩形和圓動起來

  procedureTForm.ButtonClick(SenderTObject)
  begin
  TBounceThread.Create(FalseShape
  TBounceThread.Create(FalseShape
  end
From:http://tw.wingwit.com/Article/program/Delphi/201311/25059.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.