线程的核心应用(DoubleCat)
?
{
線程的核心應(yīng)用(DoubleCat)
一,Delphi的高級應(yīng)用到了后期一點都不比C++簡單,他只能說是一種入門容易,上手容的開發(fā)
工具,到了后期高級應(yīng)用,也同是很多概念上的東西,別說java在搞一大堆概念上的東西,其實
Delphi也一樣.本部份就Delphi的線程拋開理論見本質(zhì)進行講解.
二,多線程主要應(yīng)用于網(wǎng)絡(luò)開發(fā),游戲開發(fā)中,數(shù)據(jù)庫中盡量少用(不是說不能用),因為在數(shù)據(jù)
庫開發(fā)中,為了防止數(shù)據(jù)的死鎖與寫入混亂,關(guān)系型數(shù)據(jù)庫都提供了數(shù)據(jù)庫事務(wù)主要是用來處
理死鎖與寫入混亂這個問題的.
三,線程的優(yōu)先級別屬性分為7級以tpNormal(tp=Thread Priority線程優(yōu)先的意思)為中心,
向上3級(tpHigher 1 tpHighest 2 tpTimeCritical(時間臨界) 15)
向下3級(tpLower -1 tpLowest -2 tpIdle(空閑) -15),線程的優(yōu)先級別主要用于,在同一事
件中,二個線程運行,優(yōu)先級別高的先得到運行(優(yōu)先獲得進程分配的CPU運行時間片),優(yōu)選級
別高的運行完后再運行優(yōu)先級別底的.后臺軟件中請把線程的優(yōu)先級別設(shè)成tpLower以免和前
軟件搶CUP的運行時間片,使得前臺軟件出現(xiàn)停卡的現(xiàn)像.
四,線程是個虛擬類,(包含虛擬方法的類就叫虛擬類,包含抽象方法的類就叫抽象類,不要再
把這種概念搞的更復(fù)雜了!)所以使用線程時必須定義一個線程類的子類(子類與父類的關(guān)系
往往是子大父小,這個不可以理解錯了)然后在子類中覆蓋線程類中虛擬的Execute方法,要
在線程中完成的動作(功能)全部寫在Execute里.再次說明類的派生與繼承是個什么蓋念,派
生與繼承是同一個概念,同一回事,派生類(繼承類)擁有基類(父類)的全部功能,可以在派生
類中新加功能,也可以不加.如果基類(父類)是個虛擬類抽象類,派生類必須實現(xiàn)基類中的虛
擬抽象方法.(虛擬抽向方法,就是只給出方法名稱而不給出方法的具體實現(xiàn)!如果只是虛擬方
法,那的目的是為了給泒生去用同名覆蓋,實現(xiàn)多態(tài)而已,前指示字為Public 對protected,后
指示字為override,虛擬方法在基類中必須實現(xiàn),當然可以空實現(xiàn),虛擬抽象方法必須不實現(xiàn),
方法后指示字virtual;abstract是一個整體不可分隔,這個多用于接口類)
五,線程類有個Terminated屬性 和 Terminate 方法,Terminated返回線程是否中斷,
Terminate是中斷線程. Terminated用于Execute方法內(nèi)的循環(huán)體內(nèi)檢查線程是否被外部中斷,
與Break合用如果中斷那就退出Execute代碼的執(zhí)行.如(if Terminated then Break),
而Terminate由其它線程發(fā)出,無論是子線程還是基本線程(中斷其它線程的執(zhí)行),
FreeOnTerminated(終止)屬性是設(shè)置線程中止時釋放線程所占用的資源,它也是用于
Execute方法內(nèi)部的(FreeOnTerminated := True),這個方法如果線程不會異常中斷是不需要
寫的,正帶線程中止時,系統(tǒng)自動回收線程所占用的資源,只是在有可能會異常中止的的情況
下加上這一句.這一句本來就是默認的.
六,Execute內(nèi)常用Synchronize(方法名),這里的方法名只能是線程泒生類中定義的方法.
也就是同步執(zhí)行另一個方法(即把另一個方法叫過來運行).
七,創(chuàng)建線程類實例Create(createSuspended:Boolean)方法是個帶叁的方法,表示創(chuàng)建一個
掛起的線程實例還是立即執(zhí)行的實例.如果帶叁數(shù)True,那么創(chuàng)建的實例就是掛起的.
那就要用線程實例的Resume去喚醒[ri?zju:m]為恢復(fù)的意思.
七,Sleep()過程是線程方法概念就是讓線程暫停多少毫秒,在線程睡覺中,如果有其它線程
等待運行的話,過程會立刻安排CUP運行時間片過去執(zhí)行.
八,注意:線程的Execute是個過程,無論是用CreateThread去創(chuàng)建線程還是自定義線程泒生類
去實現(xiàn)線程動作,都不要去使用有返回值的函數(shù),不要指望線程動作完成后返回一個叁數(shù)值給
你,在線程中做不到.
九,關(guān)于臨界區(qū),臨界區(qū)不光在線程的Execute代碼區(qū)內(nèi)應(yīng)用,其它地方的代碼區(qū)也能用,
它的作用是標識一段代碼同一時間內(nèi)只能由一個線程執(zhí)行.
由EnterCriticalSection開始到LeaveCriticalSection結(jié)束,
臨界變量一般為單元文件變量(一個單元內(nèi)最大的全局變量,整個單元文件內(nèi)都可以使用)
,臨界變量的創(chuàng)建與消毀可以放在窗體的創(chuàng)建與消毀時完成,也可以在單元文件的初使化
與終止化時完成,一般而言,一個單元文件用一個臨界變量就好了,當然用多個也行.線程的
同步這個概念是錯誤的,應(yīng)該叫線程異步,如,二個線程同時叫打印機打印不同的文檔,如果
不用線程異步,打印機就會隨機一下打這個線程的內(nèi)容,一下打印另一個線程的內(nèi)容,
這樣就亂套了,線程異步就是處理先讓一個線程做完他它要做的事情,再讓另一個線程開始
做事.如下是一個使用臨界區(qū)的線程異步例子.
}
unit Unit1;
interface
uses
?Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
?Dialogs, StdCtrls;
var
?CS : TRTLCriticalSection; //定義臨界區(qū)
?//TRTL意思為T=type類的前綴,RTL=RunTimeLibrary(運行時庫)
type
?TForm1 = class(TForm)
??? Button1: TButton;
??? Memo1: TMemo;
??? Button2: TButton;
??? procedure Button1Click(Sender: TObject);
??? procedure FormClose(Sender: TObject; var Action: TCloseAction);
??? procedure FormCreate(Sender: TObject);
??? procedure Button2Click(Sender: TObject);
?private
??? { Private declarations }
?public
??? { Public declarations }
?end;
type theThread = class(TThread)//定義線程類
???? protected
???? procedure Execute;override;
end;
var
?Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
?ThreadOne : theThread;//申明線程類實例
?ThreadTwo : theThread;
begin
?Memo1.Clear;
?ThreadOne := theThread.Create(False);//創(chuàng)建即時運行的線程實例
?ThreadTwo := theThread.Create(False);
end;
{ theThread }
procedure theThread.Execute;//線程泒生類Execute的實現(xiàn)部份
var
?i : Integer;
begin
?inherited;
?EnterCriticalSection(CS);//進入臨界區(qū)
?FreeOnTerminate := True;//這句可要可不要
?for i := 0 to 10 do begin
????? Form1.Memo1.Lines.Append(IntToStr(i));
????? if Terminated then Break;//這句可要可不要
?end;
?LeaveCriticalSection(CS);//離開臨界區(qū)
end;
{
如果不想用線程類方法做線程動作,只是想把一個方法讓線程去運行,那就用API函數(shù)
CreateThread,這個API的叁數(shù)如下
HANDLE?? CreateThread(
??????? LPSECURITY_ATTRIBUTES?? lpThreadAttributes, // 安全屬性特征一般為nil
??????? DWORD?? dwStackSize, // 堆大小一般為0自動大小
??????? LPTHREAD_START_ROUTINE?? lpStartAddress, //傳入方法的地址(線程開始例程),
??????????????????????????????????????????????????? 這個叁數(shù)必須給,也就是告訴創(chuàng)
??????????????????????????????????????????????????? 建的線程去做什么.
??????? LPVOID?? lpParameter, //? 是否這個線程還可以建立新線程一般為nil或0
??????? DWORD?? dwCreationFlags, // 創(chuàng)建線程的標識,一般為0自動標識
??????? LPDWORD?? lpThreadId?? //? 返回線程的ID,這個變量叁數(shù)必須給
????? );
線程方法不都是我自己定義的嗎?為什么要用CreateThrad這個API去創(chuàng)建線程?如果代碼全是
你自己寫的那都無所謂,用不著它,當在團隊中協(xié)同開發(fā)時,別人寫了一個方法在DLL中,而且必須
去同步那個DLL方法時,你別無選擇,只能用這個API的CreateThread方法去創(chuàng)建一個
立即執(zhí)行的線程
}
procedure ShowHelloWord; //定義一個方法
begin
? ShowMessage('Hello Word');
end;
procedure TForm1.Button2Click(Sender: TObject);
var
?ThreadId : DWORD;//定義變量用于裝創(chuàng)建線程后返回的ID
begin
?? CreateThread(nil,0,@ShowHelloWord,nil,0,ThreadId);//用API函數(shù)創(chuàng)建線程并執(zhí)行
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
?// DeleteCriticalSection(CS);//窗體消毀時刪除臨界區(qū)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
?//InitializeCriticalSection(CS);//窗體創(chuàng)建時創(chuàng)建臨界區(qū)
end;
initialization
InitializeCriticalSection(CS);//單元文件初使化時創(chuàng)建臨界區(qū)
finalization
DeleteCriticalSection(CS);//單元文件終止化時刪除臨界區(qū)
end.
{
隨便說一個這個end.這是與單元文件頭unit配對的,表示單元文件的代
碼區(qū)結(jié)束,unit標識單元代碼區(qū)開始.unit…end.標識編譯器查找單元文
件代碼區(qū)的范圍,不可以把單碼寫在unit前面(除了注釋外)
當然也不可以把代碼寫在end.后面(除了注釋外),
這個作用與java的單元文件類作用是一樣的.
關(guān)于互斥量與信號量,用法差不多,知道有這個概念就行,當delphi提供多種方
法時,一定要精通一種方法.
?????????? DoubleCat
}
?
轉(zhuǎn)載于:https://www.cnblogs.com/28088191/archive/2011/03/28/1997870.html
總結(jié)
以上是生活随笔為你收集整理的线程的核心应用(DoubleCat)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eclipse性能优化
- 下一篇: linux系统几个重要图