程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi中的線程類(2)(2)

Delphi中的線程類(2)(2)

編輯:Delphi

現在假設在一個兩個線程的應用中用Inc進行加一操作可能出現的一種情況:

1、線程A從內存中讀出數據(假設為3)

2、線程B從內存中讀出數據(也是3)

3、線程A對數據加一(現在是4)

4、線程B對數據加一(現在也是4)

5、線程A將數據存入內存(現在內存中的數據是4)

6、線程B也將數據存入內存(現在內存中的數據還是4,但兩個線程都對它加 了一,應該是5才對,所以這裡出現了錯誤的結果)

而用InterlockIncrement過程則沒有這個問題,因為所謂“原語”是一種不 可中斷的操作,即操作系統能保證在一個“原語”執行完畢前不會進行線程切換 。所以在上面那個例子中,只有當線程A執行完將數據存入內存後,線程B才可以 開始從中取數並進行加一操作,這樣就保證了即使是在多線程情況下,結果也一 定會是正確的。

前面那個例子也說明一種“線程訪問沖突”的情況,這也就是為什麼線程之 間需要“同步”(Synchronize),關於這個,在後面說到同步時還會再詳細討 論。

說到同步,有一個題外話:加拿大滑鐵盧大學的教授李明曾就Synchronize一 詞在“線程同步”中被譯作“同步”提出過異議,個人認為他說的其實很有道理 。在中文中“同步”的意思是“同時發生”,而“線程同步”目的就是避免這種 “同時發生”的事情。而在英文中,Synchronize的意思有兩個:一個是傳統意 義上的同步(To occur at the same time),另一個是“協調一致”(To Operate in unison)。在“線程同步”中的Synchronize一詞應該是指後面一種 意思,即“保證多個線程在訪問同一數據時,保持協調一致,避免出錯”。不過 像這樣譯得不准的詞在IT業還有很多,既然已經是約定俗成了,本文也將繼續沿 用,只是在這裡說明一下,因為軟件開發是一項細致的工作,該弄清楚的,絕不 能含糊。

扯遠了,回到TThread的構造函數上,接下來最重要就是這句了:

FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);

這裡就用到了前面說到的Delphi RTL函數BeginThread,它有很多參數,關鍵 的是第三、四兩個參數。第三個參數就是前面說到的線程函數,即在線程中執行 的代碼部分。第四個參數則是傳遞給線程函數的參數,在這裡就是創建的線程對 象(即Self)。其它的參數中,第五個是用於設置線程在創建後即掛起,不立即 執行(啟動線程的工作是在AfterConstruction中根據CreateSuspended標志來決 定的),第六個是返回線程ID。

現在來看TThread的核心:線程函數ThreadProc。有意思的是這個線程類的核 心卻不是線程的成員,而是一個全局函數(因為BeginThread過程的參數約定只 能用全局函數)。下面是它的代碼:

function ThreadProc(Thread: TThread): Integer;
var
  FreeThread: Boolean;
begin
  try
   if not Thread.Terminated then
   try
    Thread.Execute;
   except
    Thread.FFatalException := AcquireExceptionObject;
   end;
  finally
   FreeThread := Thread.FFreeOnTerminate;
   Result := Thread.FReturnValue;
   Thread.DoTerminate;
   Thread.FFinished := True;
   SignalSyncEvent;
   if FreeThread then Thread.Free;
   EndThread(Result);
  end;
end;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved